In this academy post we are going to show how to create your own HTML Widget using icCube Reporting 6. What are Widgets ? They allow for defining your own visualization charts (html/javascript), add options to them and save them so it can be reused in other reports. Once published users without technical knowledge can use them as any other charts in icCube.
For this you’ll need some html and javascript knowledge.
The first step is deciding what kind of visualization we want. Do no underestimate this task and ideally this is to be done by a designer that will help you giving a professional and consistent look to your reports. If you don’t have these resources in-house you might contact icCube or use freelancers on one of the existing available freelancers platform.
Let’s start. Our first task is to decide what kind of visualization we want and how our widget should look like.
The left is an example on how the widget should look like, the right part defines the parameters that will come from the data query. On top of these parameters, we will add the widgets background color. For the image, we will use the fonts that are freely available from Font Awesome but you can change this with any image or icon that better suits your business.
With this image draft, ok we’re cheating it’s also the final version, we will create an html version of the chart. It’s not the goal of this post to go over the technical details how do it, but you can check and play with the final version in codepen. Pay attention that the widget is going to be included into the icCube reporting and inserted into a div with a defined width and height that the report user can freely define.
[Hint] When using css classes you should ensure there is no name collision with other html components. We’re going to prefix all Academy examples with ic3a- , that should be unique in the whole html page.
Now we are ready to start integrating into icCube our new widget.
The Data
Before starting with the widget lets spend a bit of time on the data. The widgets will use the parameters from an MDX query that a result should look like :
Amount | Difference from previous year | Icon | |
---|---|---|---|
License | $4 500 | +23% | fa-bicycle |
Where License is our AmountLabel, and Difference from previous year is our Amount2Label. We could alternatively add two additional measures for the label that is more verbose.
The MDX query in our standard MDX Sales schema would look like :
[icCubeMdx]WITH MEMBER [Measures].[Difference Previous Day] AS PercN( [Measures].[Count] , ( [Time].[Year].prevMember , [Measures].[Count] ) ) , FORMAT_STRING="percent" MEMBER [Measures].[IconName] AS CASE WHEN [Product].[Product].currentMember is [Product].[Product].[Category].[License] THEN "fa-cubes" ELSE "fa-phone" END SELECT {[Measures].[Count],[Measures].[Difference Previous Day],[Measures].[IconName]} ON 0, {[Product].[Product].[Category]} on 1 FROM [Sales] WHERE [Time].[Year].[2007][/icCubeMdx]
The Visualization
From here we’re starting to work on the core of creating a new widget with icCube’s latest reporting tool, it’s time to start icCube reporting tool.
1 . Copy the css to the report
Here we have two options, we could directly inject the css into the html style attribute or add the css classes to the whole reporting (you might also add the css just for the report in Configuration / Report CSS ).
For this example we will copy the css, on the bottom of the page, to the common css (Admin / Common CSS) so it’s available on all reports.
2 . Create a new report and add an empty chart, ‘Chart/Widget’.
3. Now copy and paste the MDX statement into our query
4. Navigate to the ‘Data Render’.
Here we are. A widget template is divided in two main parts. Properties and Options. Properties define new fields that will be seen as widget options and allow the end user to easily parametrize the widget. In our example we’re going to define one properties, background-color.

You can see in the left how the two new properties fields that we’re going to use in the options part.
The option part has 4 fields, Initial HTML, HTML, On Data Received and After Render.
Initial HTML and HTML are two static text fields that define the html code the widget will render without any data and after receiving the query result. ‘On Data Received’ field allows for creating on the fly the html each time a new request result is received by the widget. Once the html is available it’s going to be inserted into the DOM (browser page). ‘After Render’ allows for working directly on the DOM , binding events, using jquery and creating complex html/javascript effects.
For this example we’re going to put all code in the ‘After Render’, but feel free to use the other fields as well. The code is document so it should be easy to understand.
function(context, node, props) { // debugger; //uncomment to debug using browser's debugger // Jquery node for the widget $node = $(node).html(" <div class='ic3a-container'> "); // html code for our boc var htmlTemplate = " <div class='ic3a-mini-box-c'> " + " <div class='ic3a-mini-box' id='$id$'> " + "<i class='ic3a-sep fa'></i>" + " <div class='value'>$value$</div> " + " <div class='measure'>$valueLabel$</div> " + " <div class='description'><span class='diff'>$valueDif$</span> <span class='description-text'>$labelDif$</span></div> " + "</div> </div> </div> "; // the actual html node where we will insert the boxes var $widget = $node.find(".ic3a-container").empty(); // for each row create a box for (var r = 0, h = context.rowsCount; r < h; r++) { // the field values for the box var labelR = context.rowLabel(r); var labelL = context.columnLabel(1); var val = context.cellFValue(r, 0); var valDiff = context.cellFValue(r, 1); // this creates an uniqueId on the whole report var id = ic3.uniqueId("ic3-mini-box"); // let's do a straight forward string substituion for all our parameters var htmlWdiget = htmlTemplate.replace("$id$",id).replace("$value$",val) .replace("$valueLabel$",labelR).replace("$valueDif$",valDiff).replace("$labelDif$",labelL); // append the html code, now it's in the DOM (visible) $widget.append(htmlWdiget); // for this parameters let's do a bit of JQuery, but a replace string // would be fine too. var color = props.backgroundColor(r,0); var iconClassName = context.cellFValue(r, 2); // direct manipulation/substituion on DOOM var $mWidget = $widget.find("#" + id); $mWidget.css('background-color', color); $mWidget.find(".fa").addClass(iconClassName); } }
The debugger code that is commented when uncommented allows for debugging the code when your browser debugger is active. The browser debugger will stop at the js statement, yes this is amazing.
Now our widget is finished and we can test it. Once we are fine with our widget we can save it, provided you’ve the rights, as a template to be reused in any of the reports.
icCube is deployed with a couple of already made Html Templates, feel free to check how they are implement as the code is available. For example, the ‘Progress Bar’ is implemented like an html template that is a different way to implement a template. D3 examples are implemented more like this example, pure javascript code.
CSS Code
.ic3a-container { width: 100%; color: white; } .ic3a-mini-box-c { display: inline-block; width: 500px; } .ic3a-mini-box { height: 150px; margin: 15px; padding: 20px; background-color:red } .ic3a-mini-box i { display: block; height: 100%; line-height:100px; font-size: 60px; width: 100px; float: left; text-align: center; border-right: 2px solid rgba(255, 255, 255, 0.5); margin-right: 20px; padding-right: 20px; color: white; } .ic3a-mini-box .value { font-size: 2em; } .ic3a-mini-box .measure { font-size: 1.5em; } .ic3a-mini-box .description { margin-top: 15px; }
By David Alvarez