🇨🇦 SAP Analytics Cloud – How to Create a Dynamic Bar Chart with 2 Color Patterns

It might seem like a simple task. However, getting the chart above in SAC isn’t as straightforward and it requires careful steps and attention to detail. In this tutorial, we’ll go through the process, step by step, on how to create a visually stunning hybrid bar chart.

Example

To begin, open a blank canvas in SAC and add a Chart element. Select your preferred data model for the chart.

Creating Actuals Restricted Accounts

  1. Head to the builder panel and navigate to the Accounts section. Click on the “+Add Account” button and choose “Add Calculation.”
  2. Opt for a “Restricted Account” as the account type.
  3. Assign the name “actuals” to the account and ensure it aligns with your desired metric.
  4. Under dimensions, select Date and then Select by Range
    • Modify the “Current Date” option from “System Date” to “+Create Current Date Input Control.”
    • Provide a name for the Current Date Input Control and set the granularity to “Month.”
    • Click “Ok”
  5. Enable the “Include Range up to Current Time Interval” option in the “Range 1” section, allowing users to adjust the range as per their preferred month.
  6. Click “OK”
  7. Add another dimension by selecting “+Add a Dimension” after Date and choose “Version.” Opt for “Select by Member” and select your desired “Actual” version.
  8. Click “OK”
  9. Confirm that the “Enable Constant Selection” toggle is on and only the Version dimension is selected, excluding Date.
  10. Click “OK” to finalize the creation of the account.

Creating the Full Year Forecast Restricted Account

Next, let’s duplicate the Actuals account and tailor it to represent the Forecasted values.

  • Click on the three dots of the Actuals account you just created and select “Duplicate.” This duplication serves as the foundation for the second measure.
  • Click on the three dots of the duplicated account and choose “Edit Calculation.”
  • Rename the account as “Full Year Forecast” and adjust the date dimension value to encompass the entire year of 2023. Set the Version as “Forecast.”
  • Click “OK.”

Creating the Forecast Restricted Account

To exclusively display the forecasted period, we’ll create a calculated account that calculates the difference between the Full Year Forecast and Actual accounts.

  • Next, remove the Full Year Forecast account from the widget.
  • Configure the bar chart by selecting the Stacked Bar/Column option and changing the orientation to Vertical.
  • Add a measure and a date dimension to the chart.
  • Ensure that the builder panel reflects these selections.

Styling and Formatting

  • Scroll down to the styling panel and activate the “Avoid Data Label Overlap” option to prevent the display of zeros.
  • Click on the chart, then select “Show/Hide” from the three dots on the top right corner, and disable Data Labels.

  • Play around with different colors for the categories and background to maximize the visual impact of the chart.

Observe the final result by adjusting the months under the filters panel.

I hope you found this example helpful. If you have any questions or suggestions, please leave a comment below.

Thanks for reading, and see you next time!

Jorge Rocha

Ler este artigo em Português Brasileiro

🇧🇷 SAP Analytics Cloud – Como editar um gráfico de Ponto Numérico utilizando CSS

Fala pessoal!

Já tentou aplicar uma formatação condicional em um gráfico de Ponto Numérico e descobre só depois que ela se aplica para o elemento como um todo e não apenas para o valor primário? Pode acreditar, eu já cometi o mesmo erro incontáveis vezes.

Então para tentar encontrar uma solução, me aprofundei na documentação de CSS do SAP Analytics Cloud e encontrei umas informações muito interessantes que podem te ajudar a economizar um tempo também.

O classe CSS abaixo te permite controlar exatamente o valor que queremos formatar neste tutorial:

.sap-custom-number-chart-secondary-values:
* Descrição: Classe CSS para numeros de um gráfico no valor secundário;
* Propriedades: font-family, font-size, color, font-style, font-weight, text-decoration;
* Descendentes: N/A;
* Pseudos: N/A;

Agora vamos explorar mais como a classe CSS mencionada acima pode ser aplicada ao elemento de Ponto Numérico. Para exemplificar melhor, vamos identificar quais são os valores primários (primary) e secundários (secondary) em um elemento:

Primary and secondary values in a numeric widget

O principal objetivo deste post é demonstrar como ignorar a formatação condicional que é aplicada automaticamente no valor secundário através de CSS, garantindo que apenas os valores primários sejam impactados pela formatação condicional.

Exemplo

A resultado abaixo é o que estamos tentando replicar:

Objetivo final do tutorial
Actual (Realizado) РBudget (Or̤amento) РMonthly Volume (Volume Mensal)

Passo 1: Primeiramente, crie uma nova tela de história. Em seguida adicione um elemento gráfico para a tela. Depois de adicionado, poderemos modificar da forma que queremos. Neste exemplo vamos selecionar o gráfico de “Ponto Numérico”.

Passo 2: Agora que temos nosso gráfico criado, é hora de popular com dados. Adicione uma conta ao valor primário, uma conta ao valor secundário e uma medida (adicione também uma versão caso nao esteja trabalhando com medidas de restrição).

Passo 3: Agora podemos criar a formatação condicional que compara o valor contido na conta primária contra o valor na conta secundária. Isso vai nos permitir visualizar de forma rápida quando nossos valores realizados e orçados estão dentro ou fora do esperado.

Passo 4: Se quisermos ir um passo além e personalizar a aparencia do elemento ainda mais, podemos editar o estilo CSS. Para fazer isso, siga os passos abaixo:

  • Clique no ícone de pincel localizado nas Configurações globais. O painel CSS vai abrir após clicar.

  • Copie o pedaço de código abaixo que passa um código de cores HEX para o valor secundário:
.chart .sap-custom-number-chart-secondary-values {
    color: #58595b;
}
  • Cole o código dentro do painel CSS. Lembre-se de alterar a seleção para gráfico.

Passo 5: Para garantir que a customização CSS seja aplicada ao gráfico, precisamos adicionar o nome da classe criada dentro do gráfico de Ponto Numérico. Aqui vai o exemplo de como fazer isso:

  1. Selecione o elemento gráfico.
  2. Vá ao painel de Definição de Estilo e licalize o campo “Nome da Classe CSS”.
  3. Escreva “chart” como o nome da classe CSS e aperte enter.

Passo 6: Agora você pode salvar sua história e ir para o modo de visualização e ver o novo estilo.

As outras formatações que você vê no elemento são simplesmente elementos cosméticos, tais como contorno e tamanho de fonte para torná-lo mais apresentável.

Espero que você tenha curtido e achado esse exemplo útil. Se você tiver alguma pergunta ou sugestão, deixe um comentário abaixo.

Obrigado e até a próxima!

Jorge Rocha

Read this article in English.

🇨🇦 SAP Analytics Cloud – How to enhance Numeric Point widgets through CSS

Hey everyone!

Have you ever tried to apply conditional formatting to a Numeric Point widget, only to find out that it affects the entire widget instead of just the primary value? Trust me, I’ve been there countless times myself.

I embarked on a quest to find a solution, delving into the depths of SAP’s CSS documentation. And guess what? I discovered some valuable info that can save you from the same problem.

This following CSS class allows you to control the exact value we’re trying to change:

.sap-custom-number-chart-secondary-values:
* Description: CSS class for number chart secondary values;
* Properties: font-family, font-size, color, font-style, font-weight, text-decoration;
* Descendants: N/A;
* Pseudos: N/A;

Now, let’s explore more how the CSS class mentioned above can be applied to the Numeric Point widget. To provide a clearer picture, let’s identify the primary and secondary values on the widget itself:

Primary and secondary values in a numeric widget

The primary goal of this blog post is to demonstrate how you can overwrite conditional formatting colors in the secondary value, ensuring that only the primary value responds to the conditional formatting rules.

Example

Here’s what we’re aiming to achieve:

End goal of the tutorial

Step 1: To get started, create a new story in your canvas. Begin by adding a Chart element to your canvas. Once added, we can modify its format to suit our needs. In this case, we’ll change the chart format to “Numeric Point.”

Step 2: Now that we have our chart in place, it’s time to populate it with data. Add one account to the primary value and another to the secondary value. Additionally, include a measure (and a version if you’re not working with measures restricted on the version).

Step 3: We can now create color thresholds (Conditional formatting) against the account on the secondary value. This will allow us to visually highlight important points, which is the comparison of actuals vs budget.

Step 4: If we want to take it a step further and personalize its appearance, we can edit the CSS style. To do so, follow the steps below:

  • Click on the paintbrush icon located under Global Settings. This will open up the CSS page.

  • Copy the following code snippet:
.chart .sap-custom-number-chart-secondary-values {
    color: #58595b;
}
  • Paste the code into the CSS Class Name field. Remember to set chart as the widget to receive the formatting.

Step 5: To ensure that our CSS customization is applied to the chart, we need to add the chart class to the CSS Class Name field in the Styling panel. Here’s an example of how to do it:

  1. With the widget selected.
  2. Locate the CSS Class Name field in the Styling panel.
  3. Enter “chart” as the CSS class name and hit enter.

Step 6: You can now save your story and switch to view mode to see how the new styling has been applied.

The other formatting you see on this widget is simply cosmetic changes such as borders and font size to make it look more presentable.

I hope you found this example helpful. If you have any questions or suggestions, please leave a comment below.

Thanks for reading, and see you next time!

Jorge Rocha

Ver este artigo em Português Brasileiro

🇨🇦 SAP Analytics Cloud – How to Simplify Input Control Management with .setSelectedMembers API

Hey everyone!

SAP has added a very useful API to set active dimension members on input controls to SAP Analytics Cloud called .setSelectedMembers().

This might not have grabbed all the attention it deserves, but trust me, it’s a game-changer when it comes to managing input controls.

In this brief tutorial, I’ll walk you through the capabilities of the .setSelectedMembers() API using two examples. Imagine you have a dashboard with tables linked to multiple data models, and to make things more challenging, these tables have restricted measures. Dealing with numerous custom input controls can be a real pain, right?

Here’s the deal: You can easily fetch the members selected from just one input control, store them in a variable, and then effortlessly pass them along to other input controls using the .setSelectedMembers() API. No more wasting time flipping selections in many different input controls.

Here’s a simple example first:

Example 1

Let’s say, for example, that you have two input controls (filters) in your story, and they are linked to two different models that contain the same Version dimension. The goal here is to ensure that the content of the first input control matches that of the second.

To achieve this, follow these steps:

  • Click on the fx button of the first input control that you want to select (Version_1).
  • Write the following code onSelect:
//Get selected member from Input control Version_1
var inputVersion = this.getInputControlDataSource().getActiveSelectedMembers();

//Set the same version to the second Input control Version_2.
Version_2.getInputControlDataSource().setSelectedMembers(inputVersion);

As explained in the comments, line 2 defines a variable to store the selected member, and line 5 passes it to the other input control. This method can be applied even if you have more than two input controls.

After saving the story, switch to View mode.

Here’s the final output in view mode:

Example 2

Now, let’s explore a more advanced example that adds some logic to the way we control the second input control.

In this scenario, we have two Date input controls. However, instead of having the same selection for both always, we want to ensure that the Date_1 filter drives the second one, while also ensuring that the Date_2 filter always represents the month prior to Date_1.

To achieve this, follow these steps:

  • Click on the fx button of the first input control that you want to select (Date_1).

Write the following code onSelect:

  • Get the selected member from the Input control Date_1.
var inputMonth = this.getInputControlDataSource().getActiveSelectedMembers();
  • Extract the year and month from the input control ID, which looks something like this: [Date].[YM].&[YYYYMM].
var year = inputMonth[0].id.slice(-7, -3);
var month = inputMonth[0].id.slice(-3, -1);
  • Convert the extracted strings to integers.
var yearInt = ConvertUtils.stringToInteger(year);
var monthInt = ConvertUtils.stringToInteger(month);
  • Calculate the previous month.
if (monthInt === 1) {
  yearInt--;
  monthInt = 12;
} else {
  monthInt--;
}
  • Check if the month is lower than 10 and add a leading zero if necessary.
if (monthInt < 10) {
  month = "0".concat(ConvertUtils.numberToString(monthInt));
}
  • Create the previousMonth variable by combining the year and month.
var previousMonth = ConvertUtils.numberToString(yearInt).concat(month);
  • Set the previousMonth to the second Input control Date_2.
Date_2.getInputControlDataSource().setSelectedMembers(previousMonth);
  • This code snippet grabs the ID of the selected member on the Date_1 filter, manipulates the strings to extract the previous month, and then passes it to the second input control. Imagine the possibilities this approach offers for different applications!

Here’s the complete code snippet:

//Get selected member from Input control Date_1
var inputMonth = this.getInputControlDataSource().getActiveSelectedMembers();

//Extract year and month from the input control id that looking something like this: [Date].[YM].&[YYYYMM]
var year = inputMonth[0].id.slice(-7, -3);
var month = inputMonth[0].id.slice(-3, -1);

//Convert strings to Integers
var yearInt = ConvertUtils.stringToInteger(year);
var monthInt = ConvertUtils.stringToInteger(month);

//Calculates previous month
if (monthInt === 1) {
  yearInt --;
  monthInt = 12;
} else {
  monthInt --;
}

//If statement checks if month is lower than 10 and adds leading zero if necessary
if (monthInt < 10) {
	month = "0".concat(ConvertUtils.numberToString(monthInt));

	var previousMonth = ConvertUtils.numberToString(yearInt).concat(month);
}

//Set the previousMonth to the second Input control Date_2
Date_2.getInputControlDataSource().setSelectedMembers(previousMonth);

After saving the story, switch to View mode. Here’s the final output in action:

Limitations

As mentioned by Orla Cullen here. This API does not support input controls that show:​

  • Unbooked members
  • Excluded members
  • Range filters and advanced filters

I hope you found these examples helpful. If you have any questions or suggestions, please leave a comment below.

Thanks for reading, and see you next time!

Jorge Rocha

Article in Brazilian Portuguese