Technical Articles
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
PART 1: RECEIVER.HTML
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 + “//” + window.location.host + “/” + “controller.html ” + “?token=” + token
3. [Optional] Shorten the remotePageUrl (e.g. use bitly.com)
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, window.top.postMessage(action.action + “:” + action.value, “<your SAC tenant>”);
PART 2: CONTROLLER.HTML
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:
- Show Input Controls according to Application content design
- Parse window.location to get token
- When user triggers actions:
POST https://server:4000/action
{“token”: token, “actions”: [{“action”: “YOUR_ACTION_TYPE”, “value”: “YOUR_ACTION_VALUE”, “ts”: new Date().getTime()}]}
PART 3: SERVER.JS
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();
app.use(bodyParser.json({
limit: ‘1mb’
}));
app.use(bodyParser.urlencoded({
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] = [];
res.json({
“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] = [];
}
res.json({
“actions”: actions
});
});
app.post(‘/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];
res.json({
“actions”: actions
});
} else {
res.json({
“error”: “token is not found”
});
}
});
app.use(‘/’, function(req, res, next) {
res.json({
“nodejs express”: new Date().getTime()
});
});
app.listen(process.env.PORT || 4000);
PART 4: ANALYTIC APPLICATION
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”) {
H_Time_Dropdown.setSelectedKey(value);
InputHandlers.H_Time_Dropdown_onSelect();
}
}
}
}
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)
SUMMARY
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.
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.
Thanks
Vishal Mahajan
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.
Thanks,
Jason
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.
Thanks in advance.
Darshan SAVANI