Skip to Content
Technical Articles
Author's profile photo Jason Yang

Build a Smart Analytic Application that Connects Big Screen, Phone and People

Using SAP Analytics Cloud you can not only build professional dashboards, but also sophisticated smart analytic applications that integrate with other applications either SAP applications or third-parties.

I would like to share with you an example about how to build an app that fully leverages the big screen, remotely controls interactions via mobile phone and triggers Search to Insights. Hope this could bring you some inspirations when you have similar use cases.

In the demo below, imagine you are sitting in a meeting room with big screens displaying the analytic app. You use your mobile phone to scan the QR code on the app to open the controlling page. Then interact with the controlling page on your mobile phone to remotely control the app on the big screen. Additionally, you can use the voice recognition to open the Search to Insight tool, a natural language query interface, on your big screen to obtain insights about your data instantly.

After looking at the demo, do you wonder how to build it? Four major parts are involved:

Note: In this case, Action Sync Server (server.js) is deployed on my Node.js as https://server:4000


It is a HTML page that is embedded in the analytic app to generate the QR code and pass the command actions from the mobile phone to the host analytic app via PostMessage API.

It has two purposes:

Generate the QR Code for URL of controller.html

1. Connect to the Sync Service (server.js) to GET https://server:4000/connect to create a MQ channel and get channel UUID as token

2. Parse window.location to get:

remotePageUrl = window.location.protocol + “//” + + “/” + “controller.html ” + “?token=” + token

3. [Optional] Shorten the remotePageUrl (e.g. use

4. Generate and Show QR Code by the (shortened) remotePageUrl (e.g. https://server:4000/controller.html?token=123456)

5. User scan QR code and open remotePageUrl (controller.html)

Read Command Actions and Pass them to the Host Analytic App

1. Every 1500ms GET https://server:4000/action?token=123456&random to read actions from the MQ channel by token (token is actually channel UUID)

2. If Actions are returned, + “:” + action.value, “<your SAC tenant>”);



It is a HTML page that runs on your mobile phone after you scan the QR code.

You can freely design the web page in the way that you would like the end user to interact with by referring to the contents in your app. For instance, switch the time periods, open and close the popups respectively for Gross Margin, Quantity Sold and Discount as we shown in our example below. You can also integrate with voice recognition service to generate the UI commands in a very natural way.

sample URL https://server:4000/controller.html?token=123456 

The HTML page will:

  1. Show Input Controls according to Application content design
  2. Parse window.location to get token
  3. When user triggers actions:
    POST https://server:4000/action
    {“token”: token, “actions”: [{“action”: “YOUR_ACTION_TYPE”, “value”: “YOUR_ACTION_VALUE”, “ts”: new Date().getTime()}]}


It is a Sync Service running on server for instance Node.js to:

1. Generate token for MQ channel

2. Receive commands from controller.html with route methods

3. Pass the commands to the receiver.html with route methods

Here is a sample server.js that runs on the node.js. (you can copy and save it as server.js file)

var express = require('express');

var bodyParser = require(‘body-parser’);

var app = express();


limit: ‘1mb’



extended: false


app.use(express.static(__dirname + ‘/public’));

// {

// “”: [{

// “ts”: 1554113602367,

// “action”: “postKeyword”,

// “value”: “a, b, c”

// }]

// }

var connections = {};

app.get(‘/connect’, function(req, res, next) {

var token = “T-” + String(Math.random()).substring(2);

connections[token] = [];


“token”: token



app.get(‘/action’, function(req, res, next) {

var token = req.query.token;

var keep = req.query.keep;

var actions = connections[token];

if (!keep) {

connections[token] = [];



“actions”: actions


});‘/action’, function(req, res, next) {

var token = req.body.token;

var actions = connections[token];

if (actions) {

connections[token] = actions.concat(req.body.actions);

actions = connections[token];


“actions”: actions


} else {


“error”: “token is not found”




app.use(‘/’, function(req, res, next) {


“nodejs express”: new Date().getTime()



app.listen(process.env.PORT || 4000);



In the analytic application’s onPostMessageReceived event, it parses message to get cmd and perform cmd logic, like switch the time periods, open and close the popup for Gross Margin.

Application– onPostMessageReceived: function(message: string, origin: string) {

if (appInitialized) {

// parse message to get cmd and perform cmd logic

var actionPair = message.split(“:”);

if (actionPair.length === 2) {

var type = actionPair[0];

var value = actionPair[1];

if (type === “H_Time_Dropdown”) {







API to use the Search to Insights in SAP Analytics Cloud, analytics designer:

//Open the Search to Insights dialog with your questions

SearchToInsight_1.openDialog(question, SearchToInsightDialogMode.Simple, false, true)



It might seem that you need to spare some efforts to create the receiver.html, controller.html and service.js. But once done, you will have a scenario that combines big screen, smart phone, and Search to Insights together. Human machine interaction becomes simpler and more natural. Communication can be more collaborative and efficient, and analytics becomes more flexible and intelligent.

Enjoy your exploration with SAP Analytics Cloud!



For questions, please visit your community topic page about SAP Analytics Cloud or post your question here.

Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Vishal Mahajan
      Vishal Mahajan

      Hi Jason,

      This is an awesome feature which you have build. Can you please share the Github link for the code. I would like to use this as a starting point to build a similar application.


      Vishal Mahajan

      Author's profile photo Jason Yang
      Jason Yang
      Blog Post Author

      Hi Vishal,

      Great to know this interests you. I have posted the high-level code here, but I cannot post all the code details due to the policy. Please ping me when you have specific questions.



      Author's profile photo Darshan Savani
      Darshan Savani

      Hi Jason Yang ,

      Thanks for sharing the amazing feature , I've tried to build server.js file using your reference code but didn't get below files tag can you please elaborate for the same.'/action', function(req, res, next)    where is /action file or how I can create ?

      app.get('/connect', function(req, res, next)   where is /connect file or how I can create ?

      Thanks in advance.
      Darshan SAVANI