Widgets

Simple table

In a simple table, you can aggregate your data with as many dimensions as your want and display the corresponding measures. You can also add computed measures. A computed measure ia a column that is obtained as a formula using other columns content. In the screenshot below (which is a folded table), the column average basket is a computed measure obtained with the formula: line[4]/line[3].

Folding

If you enable the folding option (in the rows folding menu), the user can click on the ± icons in the first column:

alt text

In a folded table, the blue row is the grand total, and pink rows are intermediate totals. The grand total is only displayed if the option Display total is enabled for at least one column. To hide the intermediate total of a column, use the column formatting option Hide intermediate total.

Free table

The free table lets you configure cells one by one. Each cell can be of mode:

  • text: the cell content is a simple text.
  • value: the cell content is obtained from one datasource query.
  • formula: the cell content is a formula based on other cells.

HTML mode

When the HTML mode is enabled for a cell, the HTML code provided will be rendered into this cell.

When a cell is in value mode, {{valueN}} can be used to obtain the Nth value configured in the data menu. Note that the Computing formula and the Numeral formatting are already applied to the value.

It's also possible to use simple expressions such as: {{value2>=0 ? "green" : "red"}} or to use any dashboard function.

Using values and numeral formatting

If you apply a numeral formatting (e.g. with option "12.34%" to format the value as a percentage), the corresponding {{valueN}} returns a string including the percentage sign. If you write {{valueN*2}} or {{valueN >0 ? "a" : "b"}} an error will be returned.

In this case, you need to convert valueN to a number. To do that, use the toNumber function, e.g.: {{toNumber(valueN)*2}}.

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div style="background-color:#fafafa;
            color:black;
            height:100%;
            text-align:left;
            padding-left:1vw;
            padding-top:1vw;
            padding-bottom:1vw;
            display:flex;
            flex-direction: column;
            justify-content:space-around">

    <div style="color:rgb(77, 144, 147); font-size:1.4vw">
        Turnover
    </div>

    <div style="font-size:2.5vw; color:rgb(0, 96, 100)">
        {{value1}}
    </div>

    <div style="font-size:1.2vw; color: {{value2>=0 ? "green" : "red"}}">
        <span class="fa fa-angle-double-{{value2>=0 ? "up" : "down"}}"></span>
        {{value2}} vs Month-1
    </div>
</div>

Bar chart

Bar configuration

  • Pad 1: value in [0,50]. Space between bars (default: 10).
  • Pad 2: value in [0,50]. Space between group of bars when data is splitted (default: 20).

Map

By default, the popup (when you click on a marker) displays the Label column and a list of the selected measures. You can configure what is displayed in the popup by filling in the Popup HTML template field.

The HTML code provided can contain formulas inside double curly brackets: {{line[1]}}. The available variables are:

  • value: contains the value of the Label column
  • line[N]: contains the value of the Nth selected measure column

Example:

1
2
3
4
5
<h4>{{value}}</h4>

<strong>Population: </strong>{{line[1]}}
<br>
<strong>Altitude : </strong>{{line[2]}}

Custom widget

The custom widget lets you code your own widget. You just need to provide the HTML code, including javascript and CSS as needed.

Using third party javascript or CSS libraries

Of course you can use 3rd party libraries such as D3.js to code widgets exactly as you want.

However, you should only load libraries that are not already used by the Serenytics application, such as D3.js. You should not try to load a different version of a library already used by Serenytics (such as Highcharts, Angular, Lodash, and more). You should not either load a different version of a CSS library already used by Serenytics, such as Bootstrap.

If you are not sure, please contact Serenytics support. Otherwise your widget could break in a future upgrade of the Serenytics platform.

How it works

You just need to write your code as if you were using it on any other web page. The only communication with Serenytics happens when retrieving the data to display in your custom widget.

For that, you need to use the strings {{rows}} and {{headers}} in your code, and they will be replaced at execution by the actual data serialized in JSON.

Example:

1
2
3
4
5
6
7
<script>
    var rows = angular.fromJson('{{rows}}');
    var headers = angular.fromJson('{{headers}}');

    console.log('data rows:', rows);
    console.log('data headers:', headers);
</script>

If you have a data set where you selected two headers Country and Amount, the following code will be executed:

1
2
3
4
5
6
7
<script>
    var rows = angular.fromJson('[["France",470], ["USA":2550]]');
    var headers = angular.fromJson('[{"name":"Country","type":"str"},{"name":"Amount","type":"float"}]');

    console.log('data rows:', rows);
    console.log('data headers:', headers);
</script>

Complete example using D3.js

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<!--
    For this example to work, you need to select 2 columns in the Data config menu.
    The first column will be used as labels and the second one as numerical values.
-->

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.3/d3.min.js"></script>

<div id="customWidget" style="overflow: auto; height: 100%;"></div>

<script>
    function main() {
        // --- Retrieve data from Serenytics template injection
        var rows = angular.fromJson('{{rows}}');
        var headers = angular.fromJson('{{headers}}');

        if (!rows) {
            console.log('data is not yet loaded');
            return;
        }

        if (typeof d3 === 'undefined') {
            console.log('d3 is not yet loaded');
            return;
        }

        // --- Create a table with inline bars using d3.js

        var table = d3.select("#customWidget").append("table");

        // Create a table with rows and bind a data row to each table row
        var tr = table.selectAll("tr.data")
            .data(rows)
            .enter()
            .append("tr")
            .attr("class", "datarow");

        // Apply style to even rows
        d3.selectAll(".datarow").filter(":nth-child(even)").attr("class", "datarow even")

        // Create the label column
        tr.append("td").attr("class", "data name")
            .text(function (d) {
                return d[0];
            });

        // Create the value column
        var formatValue = d3.format(".2f");
        tr.append("td").attr("class", "data value")
            .text(function (d) {
                return formatValue(d[1]);
            })

        // Create the chart column
        var chart = tr.append("td").attr("class", "chart");

        // Create the div structure of the chart
        chart.append("div").attr("class", "bar");

        // Create the scale to compute bar width
        var xScale = d3.scaleLinear()
            .domain([0, d3.max(rows, function (d) {
                return d[1];
            })])
            .range(["0%", "100%"]);

        // Creates the chart bars
        tr.select("div.bar")
            .style("width", "0%")
            .transition()
            .duration(500)
            .style("width", function (d) {
                return xScale(d[1]);
            });
    }

    main();
</script>

<style>
    #customWidget .chart {
        width: 300px;
        padding-left: 20px;
    }

    #customWidget .bar {
        height: 17px;
        float: left;
        background-color: steelblue;
    }

    #customWidget table {
        font: 14px sans-serif;
        vertical-align: middle;
        text-align: left;
        border-collapse: collapse;
    }

    #customWidget td,th {
        padding-top: 2px;
        padding-bottom: 2px;
    }

    #customWidget tr.even {
        background-color: whitesmoke;
    }

    #customWidget th {
        padding-left: 10px;
    }

    #customWidget td.data {
        padding-left: 10px;

    }
    #customWidget td.value {
        text-align: right;
    }
</style>