From 1e7664f2066c50120cf7e9b2251b154a26003301 Mon Sep 17 00:00:00 2001 From: lasantha Date: Thu, 22 Jun 2017 12:42:25 +0530 Subject: [PATCH] Adding new Android sense real-time analytic view --- .../analytics-view.hbs | 45 +++- .../analytics-view.js | 10 +- .../public/css/custom.css | 70 ++++++ .../public/js/device-stats.js | 209 +++++++++++------- 4 files changed, 241 insertions(+), 93 deletions(-) create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/public/css/custom.css diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/analytics-view.hbs b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/analytics-view.hbs index 8c7a7383a..10709fb9e 100644 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/analytics-view.hbs +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/analytics-view.hbs @@ -17,17 +17,44 @@ }} {{unit "cdmf.unit.lib.rickshaw-graph"}} -
+{{#zone "topCss"}} + {{css "css/custom.css"}} +{{/zone}} + +
+ + {{#each graphData}} +
+ {{#each this}} +
+
+ +

{{this}}

+
+
+
{{this}}
+
+
+
+
+
Time
+
+ + + + + + +
+
+
+ {{/each}} +
+ {{/each}} +
- - - - - View Device Analytics - - {{#zone "bottomJs"}} {{js "js/moment.min.js"}} {{js "js/socket.io.min.js"}} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/analytics-view.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/analytics-view.js index e6611f1f6..b9deeab14 100644 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/analytics-view.js +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/analytics-view.js @@ -20,6 +20,12 @@ function onRequest(context) { var log = new Log("stats.js"); var carbonServer = require("carbon").server; var device = context.unit.params.device; + // graph configuration + var graphData = { + Sensors:["accelerometer","magnetic", "gravity", "pressure", "proximity", "gyroscope"], + Realtime_Data:['battery','light','rotation'] + + }; var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; var constants = require("/app/modules/constants.js"); var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss"); @@ -36,7 +42,7 @@ function onRequest(context) { token = tokenPair.accessToken; } websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.android.sense/1.0.0?" + - + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type + "&websocketToken=" + token; + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type + "&websocketToken=" + token; } - return {"device": device, "websocketEndpoint": websocketEndpoint}; + return {"device": device, "websocketEndpoint": websocketEndpoint, "graphData":graphData}; } \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/public/css/custom.css b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/public/css/custom.css new file mode 100644 index 000000000..0b018a267 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/public/css/custom.css @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +.no-gutters { + margin-right: 0; + margin-left: 0; +} + +.no-gutters > .col, +.no-gutters > [class*="col-"] { + padding-right: 0; + padding-left: 0; +} + +.details-view-toggle-button { + display: inline-block; +} + +.custom_x_axis { + position: static; +} + +.rickshaw_legend { + color: #000000; + background: #FFFFFF; + padding: 1px 2px; +} + +.sensor_graph{ + border:0.5px solid #cecece; + margin-bottom: 30px; + padding: 20px; +} + +.sensor_graph > h3 { + text-transform: capitalize; + margin-top: 5px; +} + +.chartWrapper { + padding-top: 20px; +} + +.col-md-6 { + transition: all 400ms ease; + opacity: 1; +} + +.max{ + width: 100%; +} + +.max_hide{ + display: none; +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/public/js/device-stats.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/public/js/device-stats.js index 2745819ff..9ad8614dd 100644 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/public/js/device-stats.js +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/public/js/device-stats.js @@ -19,88 +19,84 @@ var ws; var typeId = 3; var batteryId = 5; -var gps_latId = 6; -var gps_longId = 7; -var accelerometer_xId = 8; -var accelerometer_yId = 9; -var accelerometer_zId = 10; -var magnetic_xId = 11; -var magnetic_yId = 12; -var magnetic_zId = 13; -var gyroscope_xId = 14; -var gyroscope_yId = 15; -var gyroscope_zId = 16; -var lightId = 17; -var pressureId = 18; -var proximityId = 19; -var gravity_xId = 20; -var gravity_yId = 21; -var gravity_zId = 22; -var rotation_xId = 23; -var rotation_yId = 24; -var rotation_zId = 25; -var wordId = 26; -var word_sessionIdId = 27; -var word_statusId = 28; - -var battery; + +var accelerometer_xId = 11; +var accelerometer_yId = 12; +var accelerometer_zId = 13; + +var magnetic_xId = 16; +var magnetic_yId = 17; +var magnetic_zId = 18; + +var gyroscope_xId = 19; +var gyroscope_yId = 20; +var gyroscope_zId = 21; + +var lightId = 22; + +var pressureId = 23; + +var proximityId = 24; + +var gravity_xId = 25; +var gravity_yId = 26; +var gravity_zId = 27; + +var rotation_xId = 28; +var rotation_yId = 29; +var rotation_zId = 30; + var batteryData = []; -var light; var lightData = []; -var pressure; var pressureData = []; -var proximity; var proximityData = []; -var accelerometer; var accelerometer_xData = []; var accelerometer_yData = []; var accelerometer_zData = []; -var magnetic; var magnetic_xData = []; var magnetic_yData = []; var magnetic_zData = []; -var gyroscope; var gyroscope_xData = []; var gyroscope_yData = []; var gyroscope_zData = []; -var gravity; var gravity_xData = []; var gravity_yData = []; var gravity_zData = []; -var rotation; var rotation_xData = []; var rotation_yData = []; var rotation_zData = []; -var palette = new Rickshaw.Color.Palette({scheme: "classic9"}); +var graphMap = {}; + +var palette = new Rickshaw.Color.Palette({scheme: "munin"}); $(window).load(function () { - battery = lineGraph("battery", batteryData); - light = lineGraph("light", lightData); - pressure = lineGraph("pressure", pressureData); - proximity = lineGraph("proximity", proximityData); - accelerometer = threeDlineGraph("accelerometer", accelerometer_xData, accelerometer_yData, accelerometer_zData); - magnetic = threeDlineGraph("magnetic", magnetic_xData, magnetic_yData, magnetic_zData); - gyroscope = threeDlineGraph("gyroscope", gyroscope_xData, gyroscope_yData, gyroscope_zData); - gravity = threeDlineGraph("gravity", gravity_xData, gravity_yData, gravity_zData); - rotation = threeDlineGraph("rotation", rotation_xData, rotation_yData, rotation_zData); - - var websocketUrl = $("#div-chart").data("websocketurl"); + graphMap["battery"]=lineGraph("battery", batteryData); + graphMap["light"]=lineGraph("light", lightData); + graphMap["pressure"]=lineGraph("pressure", pressureData); + graphMap["proximity"]=lineGraph("proximity", proximityData); + graphMap["accelerometer"]=threeDlineGraph("accelerometer", accelerometer_xData, accelerometer_yData, accelerometer_zData); + graphMap["magnetic"]=threeDlineGraph("magnetic", magnetic_xData, magnetic_yData, magnetic_zData); + graphMap["gyroscope"]=threeDlineGraph("gyroscope", gyroscope_xData, gyroscope_yData, gyroscope_zData); + graphMap["gravity"]=threeDlineGraph("gravity", gravity_xData, gravity_yData, gravity_zData); + graphMap["rotation"]=threeDlineGraph("rotation", rotation_xData, rotation_yData, rotation_zData); + + var websocketUrl = $("#stat-section").data("websocketurl"); connect(websocketUrl) }); -$(window).unload(function () { - disconnect(); -}); +window.onbeforeunload = function() { + disconnect(); +}; function threeDlineGraph(type, xChartData, yChartData, zChartData) { var tNow = new Date().getTime() / 1000; @@ -119,11 +115,14 @@ function threeDlineGraph(type, xChartData, yChartData, zChartData) { }); } + var $elem = $("#chart-" + type); + var graph = new Rickshaw.Graph({ - element: document.getElementById("chart-" + type), - width: $("#div-chart").width() - 50, + element: $elem[0], + width: $elem.width() - 100, height: 300, renderer: "line", + interpolation: "linear", padding: {top: 0.2, left: 0.0, right: 0.0, bottom: 0.2}, xScale: d3.time.scale(), series: [ @@ -133,24 +132,32 @@ function threeDlineGraph(type, xChartData, yChartData, zChartData) { ] }); - graph.render(); - var xAxis = new Rickshaw.Graph.Axis.Time({ graph: graph }); xAxis.render(); + new Rickshaw.Graph.Axis.Y({ + graph: graph, + orientation: 'left', + height: 300, + tickFormat: Rickshaw.Fixtures.Number.formatKMBT, + element: document.getElementById("y-axis-"+type) + }); + new Rickshaw.Graph.Legend({ graph: graph, element: document.getElementById('legend-' + type) - }); + }); var detail = new Rickshaw.Graph.HoverDetail({ graph: graph }); - return graph; + graph.render(); + + return graph; } function lineGraph(type, chartData) { @@ -162,12 +169,15 @@ function lineGraph(type, chartData) { }); } - var graph = new Rickshaw.Graph({ - element: document.getElementById("chart-" + type), - width: $("#div-chart").width() - 50, + var $elem = $("#chart-" + type); + + var graph = new Rickshaw.Graph({ + element: $elem[0], + width: $elem.width() - 100, height: 300, renderer: "line", - padding: {top: 0.2, left: 0.0, right: 0.0, bottom: 0.2}, + interpolation: "linear", + padding: {top: 0.2, left: 0.0, right: 0.0, bottom: 0.2}, xScale: d3.time.scale(), series: [{ 'color': palette.color(), @@ -176,8 +186,6 @@ function lineGraph(type, chartData) { }] }); - graph.render(); - var xAxis = new Rickshaw.Graph.Axis.Time({ graph: graph }); @@ -189,13 +197,13 @@ function lineGraph(type, chartData) { orientation: 'left', height: 300, tickFormat: Rickshaw.Fixtures.Number.formatKMBT, - element: document.getElementById('y_axis') + element: document.getElementById('y-axis-'+type) }); new Rickshaw.Graph.Legend({ graph: graph, element: document.getElementById('legend-' + type) - }); + }); new Rickshaw.Graph.HoverDetail({ graph: graph, @@ -206,7 +214,9 @@ function lineGraph(type, chartData) { } }); - return graph; + graph.render(); + + return graph; } //websocket connection @@ -219,60 +229,61 @@ function connect(target) { console.log('WebSocket is not supported by this browser.'); } if (ws) { - ws.onmessage = function (event) { + ws.onmessage = function (event) { var dataPoint = JSON.parse(event.data); + if (dataPoint) { var time = parseInt(dataPoint[4]) / 1000; switch (dataPoint[typeId]) { case "battery": - graphUpdate(batteryData, time, dataPoint[batteryId], battery); + graphUpdate(batteryData, time, dataPoint[batteryId], graphMap["battery"]); break; case "light": - graphUpdate(lightData, time, dataPoint[lightId], light); + graphUpdate(lightData, time, dataPoint[lightId], graphMap["light"]); break; case "pressure": - graphUpdate(pressureData, time, dataPoint[pressureId], pressure); + graphUpdate(pressureData, time, dataPoint[pressureId], graphMap["pressure"]); break; case "proximity": - graphUpdate(proximityData, time, dataPoint[proximityId], proximity); + graphUpdate(proximityData, time, dataPoint[proximityId], graphMap["proximity"]); break; case "accelerometer": - dataUpdate(accelerometer_xData, time, dataPoint[accelerometer_xId]); + dataUpdate(accelerometer_xData, time, dataPoint[accelerometer_xId]); dataUpdate(accelerometer_yData, time, dataPoint[accelerometer_yId]); dataUpdate(accelerometer_zData, time, dataPoint[accelerometer_zId]); - accelerometer.update(); + graphMap["accelerometer"].update(); break; case "magnetic": - dataUpdate(magnetic_xData, time, dataPoint[magnetic_xId]); + dataUpdate(magnetic_xData, time, dataPoint[magnetic_xId]); dataUpdate(magnetic_yData, time, dataPoint[magnetic_yId]); dataUpdate(magnetic_zData, time, dataPoint[magnetic_zId]); - magnetic.update(); - break; + graphMap["magnetic"].update(); + break; case "gyroscope": - dataUpdate(gyroscope_xData, time, dataPoint[gyroscope_xId]); + dataUpdate(gyroscope_xData, time, dataPoint[gyroscope_xId]); dataUpdate(gyroscope_yData, time, dataPoint[gyroscope_yId]); dataUpdate(gyroscope_zData, time, dataPoint[gyroscope_zId]); - gyroscope.update(); + graphMap["gyroscope"].update(); break; case "rotation": - dataUpdate(magnetic_xData, time, dataPoint[rotation_xId]); + dataUpdate(magnetic_xData, time, dataPoint[rotation_xId]); dataUpdate(magnetic_yData, time, dataPoint[rotation_yId]); dataUpdate(magnetic_zData, time, dataPoint[rotation_zId]); - rotation.update(); + graphMap["rotation"].update(); break; case "gravity": - dataUpdate(gravity_xData, time, dataPoint[gravity_xId]); + dataUpdate(gravity_xData, time, dataPoint[gravity_xId]); dataUpdate(gravity_yData, time, dataPoint[gravity_yId]); dataUpdate(gravity_zData, time, dataPoint[gravity_zId]); - gravity.update(); + graphMap["gravity"].update(); break; } } @@ -297,7 +308,6 @@ function dataUpdate(chartData, xValue, yValue) { chartData.shift(); } - function disconnect() { if (ws != null) { ws.close(); @@ -305,6 +315,41 @@ function disconnect() { } } -function initMap() { +function maximizeGraph(graph, width,height){ + graph.configure({ + width: width*2, + height: height*2 + + }); + graph.render(); +} -} \ No newline at end of file +function minimizeGraph(graph){ + graph.configure({ + width: 366, + height: 300 + }); + graph.render(); +} + +//maximize minimize functionality +$(".fw-expand").click(function(e) { + var innerGraph= graphMap[e.target.nextElementSibling.innerHTML]; + var width = $(".chartWrapper").width(); + var height = $(".chartWrapper").height(); + + if($(this).hasClass("default-view")){ + $(this).removeClass("default-view"); + maximizeGraph(innerGraph,width,height); + $(this).parent().parent().addClass("max"); + $(this).closest(".graph").siblings().addClass("max_hide"); + $(this).closest(".graph").parent().siblings().addClass("max_hide"); + }else{ + + $(this).addClass("default-view"); + minimizeGraph(innerGraph); + $(this).parent().parent().removeClass("max"); + $(this).closest(".graph").siblings().removeClass("max_hide"); + $(this).closest(".graph").parent().siblings().removeClass("max_hide"); + } +});