7. Library functions for dashboard interaction
It is assumed that you need to create a system of interfaces (dashboard) that allow the following interaction:
Following an event launched by a widget in dashboard A, dashboard B opens and is given the parameters necessary for a widget in dashboard B to retrieve data and display it.
For example, we could have a menu dashboard, with a table that will list certain devices (e.g., vehicles, batteries, users, etc.) and a card dashboard in which a set of widgets (time trends, bar plots, pie charts, etc.) ) will show the data collected for a specific device – see figure.
By clicking on a row of the table in the dashboard menu, the dashboard card will open and each widget will independently retrieve the data to be displayed.
To allow this interaction, the following two library functions have been implemented:
- open New Dashboard
- getParams
Note: Functions are automatically included in widgets, except for externalContent. In that case you need to explicitly specify the source js file to include, e.g.,
<script type='text/javascript' src='https://www.snap4city.org/dashboardSmartCity/js/widgetsCommonFunctions.js'>
</script>
taking care to specify the absolute path.
Function: openNewDashboard
The function, to be specified in the CK Editor of the More Option panel of a widget, has the following definition
function openNewDashboard(url, target){
console.log(url)
let a = document.createElement('a');
a.target = target;
a.href = url;
a.click();
}
Input:
- url: url of the dashboard to open, any parameters to be transmitted can be added in the queue as GET, for example, if we wanted to send the ServiceUri and the model of a device we would use
https://www.snap4city.org/dashboardSmartCity/view/index.php?iddasboard=MzY3NA==&suri=' + <serviceUri> + '&model=' + <model>
- target: how to open a new dashboard, e.g. _parent, _blank, etc.
Outputs: none
Effect: Opens a new page using the specified url and target
Function: getParams
The function, to be specified in the CK Editor of the More Option panel of a widget, has the following definition
function getParams(isIFrame = false){
let queryString = null;
if(isIFrame){
queryString = window.parent.location.search;
}else{
queryString = window.location.search;
}
out_obj = {};
const urlParams = new URLSearchParams(queryString);
const entries = urlParams.entries();
for(const entry of entries) {
console.log(`${entry[0]}: ${entry[1]}`);
out_obj[entry[0]] = entry[1];
}
console.log(out_obj);
return JSON.stringify(out_obj);
}
Input:
- isIFrame (default false): specifies whether the widget implementing the function is loaded in the dashboard as an I-Frame (e.g., externalContent) or not.
Outputs:
- A JSON string containing the GET parameters retrieved from the url of the same dashboard
Example interaction
Supposing to have
By clicking on the button in dashboard A, dashboard B will open and the pie-chart will retrieve the data of a specified device and then display them
Code for actuator (e.g. impulse button)
function execute() {
let suri = 'http://www.disit.org/km4city/resource/iot/orionUNIFI/DISIT/prettoTestBattery03';
let device = 'prettoBatteryTest03';
let url = 'https://www.snap4city.org/dashboardSmartCity/view/index.php?iddasboard=MzY3NA==&suri=' + suri + '&device=' + device;
let target = '_blank';
openNewDashboard(url, target);
}
Note: openNewDashboard must be included in the execute function as it must be invoked when an event is triggered by the actuating widget (e.g. the click on the button, or the selection of a row in the widgetDeviceTable, etc.)
When the button on dashboard A is clicked, dashboard B will open with the following url
Then, on dashboard B, a pie-chart will run the following code to fetch the data of the selected device and then display it.
Receiver code (e.g. pie-chart)
let params = JSON.parse(getParams());
let suri = params.suri;
let device = params.device;
passedData= [
{
"metricId": 'http://www.disit.org/km4city/resource/iot/orionUNIFI/DISIT/' + device,
"metricHighLevelType": 'Sensor',
"metricName": 'A',
"metricType":'energyAvailable',
"serviceUri": suri,
},
{
"metricId": 'http://www.disit.org/km4city/resource/iot/orionUNIFI/DISIT/' + device,
"metricHighLevelType": 'Sensor',
"metricName": 'B',
"metricType": 'energyNotAvailable',
"serviceUri": suri,
},
{
"metricId": 'http://www.disit.org/km4city/resource/iot/orionUNIFI/DISIT/' + device,
"metricHighLevelType": 'Sensor',
"metricName": 'C',
"metricType": 'energy discharged',
"serviceUri": suri,
},
];
setTimeout(function() {
$('body').trigger({
type: "showPieChartFromExternalContent_w_AggregationSeries_3674_widgetPieChart35154",
eventGenerator: $(this),
targetWidget: "w_AggregationSeries_3674_widgetPieChart35154",
passedData: passedData
})
}, 5000);
Note: to allow the widget to load data, you need to impose a delay on $('body').trigger() using for example setTimeout(). Otherwise the widget will hang and fail to load the data.