Technical Articles
Extending SAP Analytics Cloud’s Visualization Capability with Apache ECharts
Apache ECharts is a free, powerful, interactive charting and data visualization library. Many intuitive examples can be found on its official website https://echarts.apache.org/examples/en/index.html
Bringing Apache ECharts in SAP Analytics Cloud will extend its visualization capability. In this blog post, I would like to share with you how to quickly add Apache ECharts as custom widgets into SAP Analytics Cloud using the code template.
Here is the demo shows how Apache ECharts looks like in SAP Analytics Cloud.
(source: https://echarts.apache.org/en/index.html)
Code template: add an Apache ECharts into SAP Analytics Cloud in 5 minutes
(source: https://echarts.apache.org/en/index.html)
Try it by yourself
- Create a folder structure like c:\web\echarts\prepared
- Copy following code and save it as c:\web\echarts\prepared\index.json
{ "eula": "", "vendor": "SAP", "license": "", "id": "com.sap.sac.sample.echarts.prepared", "version": "1.0.0", "name": "ECharts Prepared", "newInstancePrefix": "EChartPrepared", "description": "A sample custom widget wrapped EChart Prepared", "webcomponents": [ { "kind": "main", "tag": "com-sap-sample-echarts-prepared", "url": "http://localhost:3000/echarts/prepared/main.js", "integrity": "", "ignoreIntegrity": true } ], "properties": { "width": { "type": "integer", "default": 600 }, "height": { "type": "integer", "default": 420 } }, "methods": { }, "events": { } }
- Copy following code and save it as c:\web\echarts\prepared\main.js
var getScriptPromisify = (src) => { return new Promise(resolve => { $.getScript(src, resolve) }) } (function () { const prepared = document.createElement('template') prepared.innerHTML = ` <style> </style> <div id="root" style="width: 100%; height: 100%;"> </div> ` class SamplePrepared extends HTMLElement { constructor () { super() this._shadowRoot = this.attachShadow({ mode: 'open' }) this._shadowRoot.appendChild(prepared.content.cloneNode(true)) this._root = this._shadowRoot.getElementById('root') this._props = {} this.render() } onCustomWidgetResize (width, height) { this.render() } async render () { await getScriptPromisify('https://cdn.bootcdn.net/ajax/libs/echarts/5.0.0/echarts.min.js') const chart = echarts.init(this._root) const option = { // https://echarts.apache.org/examples/zh/index.html } chart.setOption(option) } } customElements.define('com-sap-sample-echarts-prepared', SamplePrepared) })()
- Pick an Apache ECharts example from its official website: https://echarts.apache.org/examples/en/index.html
- Copy the code from code snippet of your selected Apache ECharts example, and replace the “option” placeholder in c:\web\echarts\prepared\main.js. Remember to keep the “const” keyword before “option”
- Upload c:\web\echarts\prepared\index.json to SAP Analytics Cloud
- Start your local web server.I personally like lite-server, a very light weight web server. You can install it with two steps:
- Install NPM tool: https://www.npmjs.com/get-npm
- Install lite-server: from OS’s terminal command line: npm install -g lite-server
Then from OS’s terminal command:
- cd c:\web (this is important as the relative path is now hard-coded in index.json)
- lite-server
Congratulation! Now you can open SAP Analytics Cloud to create an Analytic Application, and you can directly add your own Apache ECharts as a widget.
Optional step: you may want to rename your custom widget, like from “prepared” to “demo”. Then follow these steps:
- Rename the folder “prepared” to “demo”
- In index.json and main.js replace all (case sensitive)
- “prepared” to “demo”
- “Prepared” to “Demo”
Further step: render SAP Analytics Cloud model data in Apache ECharts
You may also want to render SAP Analytics Cloud model data in the Apache ECharts. Supporting Model Data binding to custom widgets is already in the product roadmap (https://saphanajourney.com/sap-analytics-cloud/product-updates/sac-download-road-map/). Before that, the recommended approach is to have a hidden table that pulls the data you would like to visualize, then send the whole result set to the Apache ECharts custom widget.
var resultSet = Table_1.getDataSource().getResultSet();
EChartLifeExpectancy2_1.render(resultSet);
It would be more efficient from development perspective to parse the result set in your custom widget’s main.js as you would be able to use any third-party library to do so. The custom widget EChartLifeExpectancy2 in the demo explains the details.
The index.json of EChartLifeExpectancy2 is as below. Now we added a render function that accepts “resultset” parameter passed from SAP Analytics Cloud.
{
"eula": "",
"vendor": "SAP",
"license": "",
"id": "com.sap.sac.sample.echarts.life_expectancy2",
"version": "1.0.0",
"name": "ECharts LifeExpectancy2",
"newInstancePrefix": "EChartLifeExpectancy2",
"description": "A sample custom widget wrapped EChart LifeExpectancy",
"webcomponents": [
{
"kind": "main",
"tag": "com-sap-sample-echarts-life_expectancy2",
"url": "http://localhost:3000/echarts/life_expectancy2/main.js",
"integrity": "",
"ignoreIntegrity": true
}
],
"properties": {
"width": {
"type": "integer",
"default": 600
},
"height": {
"type": "integer",
"default": 420
}
},
"methods": {
"render": {
"description": "Render",
"parameters": [
{
"name": "resultSet",
"type": "any",
"description": "The json"
}
]
}
},
"events": {
}
}
In the main.js, it parses the “resultset” to construct the “option” that Apache ECharts accepts. As the code snippet is long, I only take a screenshot as below:
Then set the option to the chart:
myChart.setOption(option)
Then your custom widget will be able to render data coming from SAP Analytics Cloud.
Additional information
SAP Analytics Cloud Custom Widget Developer Guide is a helpful resource:
https://help.sap.com/viewer/0ac8c6754ff84605a4372468d002f2bf/release/en-US
Summary
Besides Apache ECharts, the code template can be adapted to bring other charting libraries to help your build an even more attractive analytic application.
Hope my example could give you some ideas.
Thanks for sharing, Jason! It is very helpful for customers to extend the visualizations using custom widgets.
Incredible visualization effects. Kudos for sharing, Jason.
Nice informative and insightful post. Thanks a ton Jason.
Great blog Jason, Thanks a ton for sharing this with the community.
Hi Jason,
Just a question because I tried to reproduce and it doesn't work. I specified a URL that is accessible through internet (http://3.1xx.6x.2xx:3000/prepared/main.js) to ensure the SAC platform could access it biut I think flews are not opened . How can we manage with that?
I can see the main.js file when I call this URL http://3.1xx.6x.2xx:3000/prepared/main.js
Thanks
Hi Jerome,
My default path is http://localhost:3000/echarts/prepared/main.js, have a folder "echarts" as well.
Make sure you update the path in the .json file as well if you use a different one.
Probably you could send me your sample via email if there is still an issue.
thanks,
Jason
Hi Jason,
Thanks, this is a mixed content issue as I use HTTP and not HTTPS.
Another question, I don't see how we can use Custom Widgets with Data coming from SAC sources like Excel sheets, Universes .
Could you tell me more about that or give some links that explains how to deal with that?
Thanks again
Jérôme
Sorry Jerome for the late response.
You can build SAC data model based on Excel sheets, Universe.
Currently you can directly bind a data model to a custom widget - it is on the roadmap.
The workaround is shown in my second example to have a hidden table bound to a data model, then get the resultset and send to the custom widget.
thanks,
Jason
Hi Jason Yang,
That’s a nice tutorial .I am trying to create a gantt chart custom widget application with echarts library .I am having hard time binding data into custom widget.Do I need to create an hidden table in here as well?Do you have any example of that hidden table from where custom widget will get data?I mean How does hidden table will look like?
Thank you
Hi Lutful,
A hidden table is required before SAP releases the feature of supporting data binding to custom widget.
What does a hidden table looks like depends on the complexity of the custom widget. It can be very simple like for this basic column chart: https://echarts.apache.org/examples/en/editor.html?c=bar-simple, but can be complex like the gantt chart: https://echarts.apache.org/examples/en/editor.html?c=custom-gantt-flight
A rule of thumb is that you need to carefully the sample code snippet of the specific Apache echart, and construct a hidden table with data it requires.
Thanks,
Jason
Hi Jason,
I am tried to implement your logic as you mentioned ,i am trying to implement for this gauge report.
i have created both index file and main.js file as mentioned, but i think i am facing some issue while running lite server in npm,when i upload the custom widget in SAC in application ,it is giving the below error.
can you please help me to understand the issue.
Thanks,
Kishore
Hi Teena,
The error is to too generic to tell the root cause.Do you mind sending me your code? It is better a Github link so that you don't need to paste the code here.
In your screenshot, you show the "Full Code" tab on EChart, please switch to the "Edit Example" tab, and copy the code to your main.js, make sure having"const" keyword before "option".
Thanks,
Jason
Hi Jason,
Could you please share main.js file code that contains resultset data formation (full code of render method)?
Thanks,
Girish Lakhani