How to “paint” a Thermometer Component
Purpose
Visualize Data in Design Studio as “Thermometer” in standard installation – without using an SDK development. This thermometer is for percentage values 0 to 100 %.
Basics
This component is created using the tips from my Blog “Painting” with Design Studio via CSS3.
Setting Values
There is no automatic connection to any data source, but you can set the values as shown in attached application.
Set the “base line”
“Base line” is a line which sets some custom value, you can move this between 0 and 100
// baseline between 0 and 100
var valueAsIntegerBetween0and100 = Convert.stringToInt(INPUTFIELD_2.getValue());
// baseline is aline positioned in the scale using bottom margin value
PANEL_TH_BASELINE.setBottomMargin(valueAsIntegerBetween0and100 * 2 + 100);
Set the “value”
“Value” is the visualization of the current percentage. Between 0 and 100.
// here the value must be manually calculated
var valueAsIntegerBetween0and100 = Convert.stringToInt(INPUTFIELD_1.getValue());
// the value is visualized by the hight of the corresponding PANEL
PANEL_TH_VALUE.setHeight(valueAsIntegerBetween0and100 * 2);
// assuming the base line is already set, here the "back" calculation from bottom margin to percentage value
var baselineValueBwtween0and100 = PANEL_TH_BASELINE.getBottomMargin();
baselineValueBwtween0and100 = baselineValueBwtween0and100 - 100;
baselineValueBwtween0and100 = baselineValueBwtween0and100 / 2;
// based on the difference between base line and value, different css styles can be set
if(valueAsIntegerBetween0and100 >= baselineValueBwtween0and100) {
PANEL_TH_BASE.setCSSClass("th-base th-good");
PANEL_TH_VALUE.setCSSClass("th-value th-good");
PANEL_TH_DOT.setCSSClass("th-dot th-good");
} else {
PANEL_TH_BASE.setCSSClass("th-base th-bad");
PANEL_TH_VALUE.setCSSClass("th-value th-bad");
PANEL_TH_DOT.setCSSClass("th-dot th-bad");
}
Example
Thermometer with “good” visualization
Thermometer with “good” visualization
Used CSS
.th-border-top {
border-top: 1px solid #cccccc;
}
.th-border-top-baseline {
border-top: 3px solid black;
}
.th-base {
}
.th-value {
}
.th-dot {
border-radius: 40px 40px 40px 40px / 40px 40px 40px 40px;
border: 1px solid #cccccc;
}
.th-bad {
background-color: red;
}
.th-good {
background-color: green;
}
Scripts for Data Binding
Read from data and convert to Integer
// here the value must be manually calculated
var dataValue = DS_1.getData("4FW8RN37GL043NF22OTQFXYL3", {
"0BC_PERS1": "00020"
});
// read the value from the data cell
var dataValueFull = dataValue.value;
// use formatting to get the number w/o decimal places
var dataValueString = Convert.floatToString(dataValueFull, "###");
// convert to integer and save
var valueAsIntegerBetween0and100Original = Convert.stringToInt(dataValueString);
// calculate
var valueAsIntegerBetween0and100 = valueAsIntegerBetween0and100Original;
valueAsIntegerBetween0and100 = valueAsIntegerBetween0and100 * 2;
Apllication as Example
Example Application can be downloaded from GitHub:
- ZIP Version of Repository: Release Add of Paint and Thermometer Applications · KarolKalisz/DesignStudioBiAppRepository · GitHub
- Source Code: DesignStudioBiAppRepository/SCN_THERMOMETER at master · KarolKalisz/DesignStudioBiAppRepository · GitHub
Update: use the newest version to have the application updated by two new buttons:
Link to ZIP: Release 1.1.1: Updating thermometer Example by Data Binding · KarolKalisz/DesignStudioBiAppRepository · GitHub
You need to change of course the query.
I hope you have fun with this component.
Hi Karol
I have given this a try, I downloaded the Zip file and uploaded the app but its not working as expected.
inputting values into the boxes and pressing the relevant button does nothing.
If I manually insert some figures and put them in my on startup code it works well.
However when trying to set the value from a Datasource it doesn't like it at all, just gives an error and in the error log I can see these lines
Message: org.mozilla.javascript.WrappedException: Wrapped java.lang.NullPointerException (BIAL Script#3)
Error during script processing: "PANEL_TH_BASELINE.setBottomMargin(90 * 2 + 100);
Error during script processing. Contact the Application Designer to resolve the issue
If I remove the reference to my DS_1 datasource I don't get these errors so im a little baffled. If I remove the line it is moaning about or comment it out it still moans about the first part of the script.
Any ideas?
Here is the line I have edited
valueAsIntegerBetween0and100 = Convert.stringToInt(DS_1.getDataAsString("DIEEMDTX6CJC94HO28BWVYMZQ", {"0DIVISION":"39"}));
Hi, I will try also with data source. but in the meantime:
* which release / SP are you on?
* please open the exception window and paste the callstack with nullpointer.
* perhaps you can add one more line before:
var integetToSet = valueAsIntegerBetween0and100 * 2 + 100;
PANEL_TH_BASELINE.setBottomMargin(integetToSet);
Hi Karol
I am on 1.3 SP01.
com.sap.ip.bi.zen.rt.framework.jsengine.JsEngineException: org.mozilla.javascript.WrappedException: Wrapped java.lang.NullPointerException (BIAL Script#3)
at com.sap.ip.bi.zen.rt.framework.jsengine.rhino.RhinoJsEngine.handleError(RhinoJsEngine.java:141)
at com.sap.ip.bi.zen.rt.framework.jsengine.rhino.RhinoJsEngine.doResumeScript(RhinoJsEngine.java:119)
at com.sap.ip.bi.zen.rt.framework.jsengine.JsEngine.resumeScript(JsEngine.java:53)
at com.sap.ip.bi.zen.rt.framework.jsengine.rhino.RhinoScriptInterpreterBialService.interprete(RhinoScriptInterpreterBialService.java:193)
at com.sap.ip.bi.base.command.impl.Command.interprete(Command.java:189)
at com.sap.ip.bi.webapplications.runtime.impl.page.Page.processCommandSequence(Page.java:4662)
at com.sap.ip.bi.webapplications.runtime.impl.page.Page.doProcessRequest(Page.java:2618)
at com.sap.ip.bi.webapplications.runtime.impl.page.Page._processRequest(Page.java:774)
at com.sap.ip.bi.webapplications.runtime.impl.page.Page.processRequest(Page.java:5080)
at com.sap.ip.bi.webapplications.runtime.impl.page.Page.processRequest(Page.java:5073)
at com.sap.ip.bi.webapplications.runtime.impl.controller.Controller.doProcessRequest(Controller.java:1238)
at com.sap.ip.bi.webapplications.runtime.impl.controller.Controller._processRequest(Controller.java:1088)
at com.sap.ip.bi.webapplications.runtime.impl.controller.Controller.processRequest(Controller.java:1054)
at com.sap.ip.bi.webapplications.runtime.impl.controller.Controller.processRequest(Controller.java:1)
at com.sap.ip.bi.server.runtime.sevice.impl.BIRuntimeServerService._handleRequest(BIRuntimeServerService.java:538)
at com.sap.ip.bi.server.runtime.sevice.impl.BIRuntimeServerService.handleRequest(BIRuntimeServerService.java:943)
at com.sap.ip.bi.server.execution.engine.runtime.BIExecutionEngineRuntime.executeRequest(BIExecutionEngineRuntime.java:48)
at com.sap.ip.bi.framework.base.execution.impl.BIExecutionService.executeRequest(BIExecutionService.java:54)
at com.sap.ip.bi.client.execution.AbstractExecutionServlet.handleRequest(AbstractExecutionServlet.java:161)
at com.sap.ip.bi.client.servlet.BIPrivateServlet.handleRequest(BIPrivateServlet.java:36)
at com.sap.ip.bi.client.execution.AbstractExecutionServlet.doPost(AbstractExecutionServlet.java:140)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:755)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.equinox.http.servlet.internal.ServletRegistration.service(ServletRegistration.java:61)
at org.eclipse.equinox.http.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:38)
at com.sap.ip.bi.zen.webserver.internal.ZenSessionFilter.doFilter(ZenSessionFilter.java:34)
at org.eclipse.equinox.http.servlet.internal.FilterRegistration.doFilter(FilterRegistration.java:81)
at org.eclipse.equinox.http.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:35)
at org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:132)
at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:60)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.equinox.http.jetty.internal.HttpServerManager$InternalHttpServiceServlet.service(HttpServerManager.java:386)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:669)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:457)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:229)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1075)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:384)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1009)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
at org.eclipse.jetty.server.Server.handle(Server.java:368)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:489)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:953)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1014)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:861)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:628)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Unknown Source)
Caused by: org.mozilla.javascript.WrappedException: Wrapped java.lang.NullPointerException (BIAL Script#3)
at org.mozilla.javascript.Context.throwAsScriptRuntimeEx(Context.java:1786)
at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:183)
at org.mozilla.javascript.NativeJavaMethod.call(NativeJavaMethod.java:247)
at org.mozilla.javascript.Delegator.call(Delegator.java:229)
at com.sap.ip.bi.zen.rt.framework.jsengine.rhino.shared.CustomFunction.call(CustomFunction.java:36)
at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:1701)
at org.mozilla.javascript.Interpreter.restartContinuation(Interpreter.java:914)
at org.mozilla.javascript.NativeContinuation.call(NativeContinuation.java:80)
at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:426)
at com.sap.ip.bi.zen.rt.framework.jsengine.rhino.CustomContextFactory.doTopCall(CustomContextFactory.java:54)
at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3178)
at org.mozilla.javascript.Interpreter.restartContinuation(Interpreter.java:895)
at org.mozilla.javascript.Context.resumeContinuation(Context.java:1246)
at com.sap.ip.bi.zen.rt.framework.jsengine.rhino.RhinoJsEngine.doResumeScript(RhinoJsEngine.java:109)
... 51 more
Caused by: java.lang.NullPointerException
at com.sap.ip.bi.zen.rt.components.ds.impl.DataSourceCommandResolver.getCell(DataSourceCommandResolver.java:1239)
at com.sap.ip.bi.zen.rt.components.ds.impl.DataSourceCommandResolver.getDataAsString(DataSourceCommandResolver.java:1095)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:161)
... 63 more
Tried the additional line but hasn't made any difference
looks like you have an issue with the cell celection.
please check updated content of the example, 2 new buttons are in
Perhaps you can find the issue by checking the code step by step. At least I could pass the value from the query to the integer.
I could do with a debugger in here to see what each variable is displaying each step of the way!
I have downloaded the new version and still none of the buttons do anything? I changed the datasource and the query.
try following:
after every line you can add
APPLICATION.createErrorMessage(...);
there you can print out the values.
you need to find the line which is making "nullpointer".
Doesn't work! all I get is
Error during script processing. Contact the Application Designer to resolve the issue
hmm, then one of the line is causing validation error. the only way will be to start creation of this script line by line. I mean, place first line - and the addErrorMessage() line below and execute. if works, add second line etc. at some line you will get validation isssue. what is the line?
perhaps first you can also try to pass the cell value to a simle text component to see if the selection is working well and how it is formated
It does look to be the cell selection causing issues as you said.
If I create button and add the following code and run the app and press said button I get an error saying Dum dum dum. Please Note NOTIFY is a custom component that I have loaded from SCN 🙂
NOTIFY_1.error(" Dum dum dum");
If I change code and put the following before it.
Var dataValue = DS_1.getDataAsString("DIEEMDTX6CJC94HO28BWVYMZQ", {
"0DIVISION": "39" });
Then run app and press same button, I no longer get my Error message but a Script error and to contact the admin 🙂
Not too sure how I could debug this further.
how are you initializing the data source?
try to check the code with getData() and not with getDataAsString(). when you add after every line the "APPLICATION.createErrorMessage()" then you will see all messages in the popup - this is how you can find the line which is breaking.
also, check if "39" is the key - if this is a text and the key is like "0039" or similar, then the cell cannot be found
If I put 039 as the key I get a prompt in script editor to say its not found any info for it, With 39 and hovering over it the script editor shows me the text for that item.
I think its safe to say the data is there and it can see it but its the calling of the data it doesn't like.
I have changed to getData and the same problem happens?
Its very strange, are you also using SP01? And are you in local mode or Connected Mode?
Its the line for retrieving the data that is giving the issue.
The below is attached to a button, I don't get the first message or the second, I just get he script error!
var dataValue = DS_1.getDataAsString("DIEESCJSRAKYB230F23L4Q8YU", { "0DIVISION" :"39" });
APPLICATION.createErrorMessage("Got Data");
INPUTFIELD_1.setValue(dataValue);
APPLICATION.createErrorMessage("Set Value");
I reply to the top one for better reading.
you must see an validation error when working in designer, like this one:
mouse-over says: cannot convert from datacell to string.
correct script would be:
// here the value must be manually calculated
var dataValue = DS_1.getData("4FW8RN37GL043NF22OTQFXYL3", {
"0BC_PERS1": "00020"
});
// read the value from the data cell
var dataValueFull = dataValue.value;
// use formatting to get the number w/o decimal places
var dataValueString = Convert.floatToString(dataValueFull, "###");
INPUTFIELD_3.setValue(dataValueString);
I don't have validation errors like that I have corrected them 🙂
I copied the example you have given but I just get nothing when clicking on the button.
I have a meeting now so will have to carry on with this later or tomorrow! Thanks for all your help though, I do appreciate it.
I see you still using the script "getDataAsString", please use the script I have provided with "getData" and then convert..
if you do not manage, we can make short call on private.
Hi Karol, Sorry I didn't get back to you sooner been quite busy today 🙂
I had getData as you supplied in the last script and nothing happens.
Putting an error message after the first line to retrieve the data does not display any error.
This is very weird!
Karol
There seems to be other threads with a similar issue to mine
What OS Version/architecture are you using?
What Design Studio Version/SP Are you using?
Thanks
plz contact me on karol.kalisz@sap.com - I will send you a meeting request, ok?
Hi Karol
Panic over! I was selecting 0MATERIAL_0DIVISION in my initial view and not 0DIVISION.
I didn't have 0DIVISION in my Bex Query though so not sure how Design Studio validated that I could use it?!
However once adding it to my bex query its now working 🙂
The buttons you created still don't work for me though, if I take the code and put it in on startup it works fine though.
Thanks very much for all your help and for the thermometer it has helped me massively!
All the best
good to hear that it is used.