forked from community/product-iots
Merge pull request #99 from Shabirmean/master
Adding IoTServer specific Gadgets to the portal appapplication-manager-new
commit
55353859b6
@ -0,0 +1,380 @@
|
||||
<%
|
||||
(function () {
|
||||
var TYPE = "type";
|
||||
var TABLE_NAME = "tableName";
|
||||
var TIME_FROM = "timeFrom";
|
||||
var TIME_TO = "timeTo";
|
||||
var START = "start";
|
||||
var COUNT = "count";
|
||||
var FILTER = "filter";
|
||||
var QUERY = "query";
|
||||
var SORT_SCORE_VALUE = "scoreFunc";
|
||||
var RECORDSTORE_NAME = "recordStore";
|
||||
var HTTPS_TRANSPORT = "https";
|
||||
var CONTENT_TYPE_JSON = "application/json";
|
||||
var AUTHORIZATION_HEADER = "Authorization";
|
||||
var USER_TOKEN = "user";
|
||||
var USERNAME = "username";
|
||||
var WAIT_TIME = "waitTime";
|
||||
var LOCALHOST = "localhost";
|
||||
var HTTP_USER_NOT_AUTHENTICATED = 403;
|
||||
var HTTP_INTERNAL_ERROR = 500;
|
||||
var MILLISECONDS_PER_SECOND = 1000;
|
||||
var JS_MAX_VALUE = "9007199254740992";
|
||||
var JS_MIN_VALUE = "-9007199254740992";
|
||||
var ZERO_INDEX = "0";
|
||||
var LAST_INDEX = "5000"; //Set the max value to 5000. This is to prevent accidental loading of millions of records.
|
||||
var DEFAULT_COUNT = 20;
|
||||
|
||||
var TYPE_CLEAR_INDEX_DATA = 1;
|
||||
// var TYPE_CREATE_TABLE = 2;
|
||||
// var TYPE_DELETE_BY_ID = 3;
|
||||
// var TYPE_DELETE_BY_RANGE = 4;
|
||||
// var TYPE_DELETE_TABLE = 5;
|
||||
var TYPE_GET_RECORD_COUNT = 6;
|
||||
var TYPE_GET_BY_ID = 7;
|
||||
var TYPE_GET_BY_RANGE = 8;
|
||||
var TYPE_LIST_TABLES = 9;
|
||||
var TYPE_GET_SCHEMA = 10;
|
||||
// var TYPE_PUT_RECORDS = 11;
|
||||
// var TYPE_PUT_RECORDS_TO_TABLE = 12;
|
||||
var TYPE_SEARCH = 13;
|
||||
var TYPE_SEARCH_COUNT = 14;
|
||||
var TYPE_SET_SCHEMA = 15;
|
||||
var TYPE_TABLE_EXISTS = 16;
|
||||
var TYPE_WAIT_FOR_INDEXING = 17;
|
||||
var TYPE_PAGINATION_SUPPORTED = 18;
|
||||
var TYPE_DRILLDOWN_CATEGORIES = 19;
|
||||
var TYPE_DRILLDOWN_SEARCH = 20;
|
||||
var TYPE_DRILLDOWN_SEARCH_COUNT = 21;
|
||||
var TYPE_ADD_STREAM_DEFINITION = 22;
|
||||
var TYPE_GET_STREAM_DEFINITION = 23;
|
||||
var TYPE_PUBLISH_EVENTS = 24;
|
||||
var TYPE_GET_WITH_KEY_VALUES = 25;
|
||||
var TYPE_GET_RECORDSTORES = 26;
|
||||
var TYPE_GET_RECORDSTORE_BY_TABLE = 27;
|
||||
var TYPE_WAIT_FOR_INDEXING_FOR_TABLE = 28;
|
||||
var TYPE_SEARCH_WITH_AGGREGATES = 29;
|
||||
var TYPE_REINDEX = 30;
|
||||
var log = new Log();
|
||||
var carbon = require('carbon');
|
||||
var configs = require('/configs/designer.json');
|
||||
var utils = require('/modules/utils.js');
|
||||
var JSUtils = Packages.org.wso2.carbon.analytics.jsservice.Utils;
|
||||
var AnalyticsCachedJSServiceConnector = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector;
|
||||
var AnalyticsCache = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector.AnalyticsCache;
|
||||
var cacheTimeoutSeconds = 5;
|
||||
var loggedInUser = null;
|
||||
|
||||
if(configs.cacheTimeoutSeconds) {
|
||||
cacheTimeoutSeconds = parseInt(configs.cacheTimeoutSeconds);
|
||||
}
|
||||
var cacheSizeBytes = 1024 * 1024 * 1024; // 1GB
|
||||
if(configs.cacheSizeBytes) {
|
||||
cacheSizeBytes = parseInt(configs.cacheSizeBytes);
|
||||
}
|
||||
response.contentType = CONTENT_TYPE_JSON;
|
||||
|
||||
var authParam = request.getHeader(AUTHORIZATION_HEADER);
|
||||
if (authParam != null) {
|
||||
credentials = JSUtils.authenticate(authParam);
|
||||
loggedInUser = credentials[0];
|
||||
} else {
|
||||
var token = session.get(USER_TOKEN);
|
||||
if (token != null) {
|
||||
loggedInUser = token[USERNAME];
|
||||
} else {
|
||||
log.error("user is not authenticated!");
|
||||
response.status = HTTP_USER_NOT_AUTHENTICATED;
|
||||
print('{ "status": "Failed", "message": "User is not authenticated." }');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var cache = application.get("AnalyticsWebServiceCache");
|
||||
if (cache == null) {
|
||||
cache = new AnalyticsCache(cacheTimeoutSeconds, cacheSizeBytes);
|
||||
application.put("AnalyticsWebServiceCache", cache);
|
||||
}
|
||||
|
||||
var connector = new AnalyticsCachedJSServiceConnector(cache);
|
||||
|
||||
var type = 0;
|
||||
var typeParam = request.getParameter(TYPE);
|
||||
if (typeParam != null) {
|
||||
type = parseInt(typeParam);
|
||||
}
|
||||
|
||||
if (type == 0) {
|
||||
log.error("operation type is not specified!");
|
||||
response.status = HTTP_INTERNAL_ERROR;
|
||||
print('{ "status": "Failed", "message": "Operation type is not specified" }');
|
||||
return;
|
||||
}
|
||||
|
||||
var tableName = request.getParameter(TABLE_NAME);
|
||||
if (type != TYPE_LIST_TABLES &&
|
||||
// type != TYPE_PUT_RECORDS &&
|
||||
type != TYPE_PAGINATION_SUPPORTED &&
|
||||
type != TYPE_ADD_STREAM_DEFINITION &&
|
||||
type != TYPE_GET_STREAM_DEFINITION &&
|
||||
type != TYPE_PUBLISH_EVENTS &&
|
||||
type != TYPE_WAIT_FOR_INDEXING &&
|
||||
type != TYPE_GET_RECORDSTORES) {
|
||||
if (tableName == null) {
|
||||
log.error("tableName is not provided!");
|
||||
response.status = HTTP_INTERNAL_ERROR;
|
||||
print('{ "status": "Failed", "message": "Table name param is empty" }');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var content = request.getContent();
|
||||
var contentAsString = null;
|
||||
if (content != '' && content != null) {
|
||||
contentAsString = stringify(content);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("value of content: " + contentAsString);
|
||||
}
|
||||
}
|
||||
if (connector != null && loggedInUser != null) {
|
||||
var result = null;
|
||||
switch (type) {
|
||||
case TYPE_LIST_TABLES:
|
||||
{
|
||||
result = connector.getTableList(loggedInUser);
|
||||
break;
|
||||
}
|
||||
/*case TYPE_CREATE_TABLE:
|
||||
{
|
||||
print(connector.createTable(tableName));
|
||||
break;
|
||||
}
|
||||
case TYPE_DELETE_TABLE:
|
||||
{
|
||||
print(connector.deleteTable(tableName));
|
||||
break;
|
||||
} */
|
||||
case TYPE_TABLE_EXISTS:
|
||||
{
|
||||
result = connector.tableExists(loggedInUser, tableName);
|
||||
break;
|
||||
}
|
||||
case TYPE_GET_BY_RANGE:
|
||||
{
|
||||
var from = request.getParameter(TIME_FROM);
|
||||
if (from == 'undefined') from = JS_MIN_VALUE;
|
||||
var to = request.getParameter(TIME_TO);
|
||||
if (to == 'undefined') to = JS_MAX_VALUE;
|
||||
var start = request.getParameter(START);
|
||||
var intStart = ZERO_INDEX;
|
||||
if (start != 'undefined' && start != null) {
|
||||
intStart = parseInt(start, 10);
|
||||
}
|
||||
var count = request.getParameter(COUNT);
|
||||
var intCount = LAST_INDEX;
|
||||
if (count != 'undefined' && count != null) {
|
||||
intCount = parseInt(count, 10);
|
||||
}
|
||||
result = connector.getRecordsByRange(loggedInUser, tableName, from, to, intStart, intCount, contentAsString);
|
||||
break;
|
||||
}
|
||||
case TYPE_GET_WITH_KEY_VALUES:
|
||||
{
|
||||
result = connector.getWithKeyValues(loggedInUser, tableName, contentAsString);
|
||||
break;
|
||||
}
|
||||
case TYPE_GET_BY_ID:
|
||||
{
|
||||
result = connector.getRecordsByIds(loggedInUser, tableName, contentAsString);
|
||||
break;
|
||||
}
|
||||
case TYPE_GET_RECORD_COUNT:
|
||||
{
|
||||
result = connector.getRecordCount(loggedInUser, tableName);
|
||||
break;
|
||||
}
|
||||
/*case TYPE_DELETE_BY_RANGE:
|
||||
{
|
||||
var timeFrom = Long.parseLong(request.getParameter(TIME_FROM));
|
||||
var timeTo = Long.parseLong(request.getParameter(TIME_TO));
|
||||
print(connector.deleteRecordsByRange(tableName, timeFrom, timeTo));
|
||||
break;
|
||||
}
|
||||
case TYPE_DELETE_BY_ID:
|
||||
{
|
||||
print(connector.deleteRecordsByIds(tableName, contentAsString));
|
||||
break;
|
||||
}*/
|
||||
case TYPE_CLEAR_INDEX_DATA:
|
||||
{
|
||||
result = connector.clearIndexData(loggedInUser, tableName);
|
||||
break;
|
||||
}
|
||||
/*case TYPE_PUT_RECORDS:
|
||||
{
|
||||
print(connector.insertRecords(contentAsString));
|
||||
break;
|
||||
}*/
|
||||
case TYPE_SEARCH_COUNT:
|
||||
{
|
||||
var queryString = request.getParameter(QUERY);
|
||||
if (queryString == 'undefined' || queryString == null || queryString == '') {
|
||||
result = '{ "status": "Failed", "statusCode": "400", "message": "Invalid Request" }';
|
||||
break;
|
||||
};
|
||||
|
||||
contentAsString = "{query: " + queryString + "}";
|
||||
result = connector.searchCount(loggedInUser, tableName, contentAsString);
|
||||
break;
|
||||
}
|
||||
case TYPE_SEARCH:
|
||||
{
|
||||
var queryString = request.getParameter(QUERY);
|
||||
if (queryString == 'undefined' || queryString == null || queryString == '') {
|
||||
result = '{ "status": "Failed", "statusCode": "400", "message": "Invalid Request" }';
|
||||
break;
|
||||
};
|
||||
|
||||
var count = request.getParameter(COUNT);
|
||||
if (count == 'undefined' || count == null || count == '') {
|
||||
count = DEFAULT_COUNT;
|
||||
}
|
||||
|
||||
contentAsString = "{query: " + queryString + ", count:" + count + "}";
|
||||
result = connector.search(loggedInUser, tableName, contentAsString);
|
||||
break;
|
||||
}
|
||||
case TYPE_SET_SCHEMA:
|
||||
{
|
||||
print(connector.setTableSchema(loggedInUser, tableName, contentAsString));
|
||||
break;
|
||||
}
|
||||
case TYPE_GET_SCHEMA:
|
||||
{
|
||||
result = connector.getTableSchema(loggedInUser, tableName);
|
||||
break;
|
||||
}
|
||||
case TYPE_PAGINATION_SUPPORTED:
|
||||
{
|
||||
var recordStore = request.getParameter(RECORDSTORE_NAME)
|
||||
result = connector.isPaginationSupported(recordStore);
|
||||
break;
|
||||
}
|
||||
case TYPE_WAIT_FOR_INDEXING:
|
||||
{
|
||||
var waitTimeAsString = request.getParameter(WAIT_TIME);
|
||||
var waitTime = -1;
|
||||
if (waitTimeAsString != null) {
|
||||
waitTime = parseInt(waitTimeAsString);
|
||||
}
|
||||
result = connector.waitForIndexing(waitTime * MILLISECONDS_PER_SECOND);
|
||||
break;
|
||||
}
|
||||
case TYPE_WAIT_FOR_INDEXING_FOR_TABLE:
|
||||
{
|
||||
var waitTimeAsString = request.getParameter(WAIT_TIME);
|
||||
var waitTime = -1;
|
||||
if (waitTimeAsString != null) {
|
||||
waitTime = parseInt(waitTimeAsString);
|
||||
}
|
||||
result = connector.waitForIndexing(tableName, waitTime * MILLISECONDS_PER_SECOND);
|
||||
break;
|
||||
}
|
||||
case TYPE_DRILLDOWN_CATEGORIES:
|
||||
{
|
||||
result = connector.drillDownCategories(loggedInUser, tableName, contentAsString);
|
||||
break;
|
||||
}
|
||||
case TYPE_DRILLDOWN_SEARCH:
|
||||
{
|
||||
var queryString = request.getParameter(QUERY);
|
||||
if (queryString == 'undefined' || queryString == null || queryString == '') {
|
||||
result = '{ "status": "Failed", "statusCode": "400", "message": "Invalid Request. Query string not found." }';
|
||||
break;
|
||||
};
|
||||
|
||||
var scoreFunction = request.getParameter(SORT_SCORE_VALUE);
|
||||
if (scoreFunction == 'undefined' || scoreFunction == null || scoreFunction == '') {
|
||||
result = '{ "status": "Failed", "statusCode": "400", "message": "Invalid Request. Score function not found." }';
|
||||
break;
|
||||
};
|
||||
|
||||
var count = request.getParameter(COUNT);
|
||||
if (count == 'undefined' || count == null || count == '') {
|
||||
count = DEFAULT_COUNT;
|
||||
}
|
||||
|
||||
contentAsString = "{query: " + queryString + ", recordCount:"+ count +", scoreFunction:'"+ scoreFunction +"', categories: []}";
|
||||
result = connector.drillDownSearch(loggedInUser, tableName, contentAsString);
|
||||
break;
|
||||
}
|
||||
case TYPE_DRILLDOWN_SEARCH_COUNT:
|
||||
{
|
||||
result = connector.drillDownSearchCount(loggedInUser, tableName, contentAsString);
|
||||
break;
|
||||
}
|
||||
case TYPE_ADD_STREAM_DEFINITION:
|
||||
{
|
||||
result = connector.addStreamDefinition(contentAsString);
|
||||
break;
|
||||
}
|
||||
case TYPE_GET_STREAM_DEFINITION:
|
||||
{
|
||||
result = connector.getStreamDefinition(contentAsString);
|
||||
break;
|
||||
}
|
||||
case TYPE_PUBLISH_EVENTS:
|
||||
{
|
||||
result = connector.publishEvent(contentAsString);
|
||||
break;
|
||||
}
|
||||
case TYPE_GET_RECORDSTORES:
|
||||
{
|
||||
result = connector.getRecordStoreList();
|
||||
break;
|
||||
}
|
||||
case TYPE_GET_RECORDSTORE_BY_TABLE:
|
||||
{
|
||||
result = connector.getRecordStoreByTable(loggedInUser, tableName);
|
||||
break;
|
||||
}
|
||||
case TYPE_SEARCH_WITH_AGGREGATES:
|
||||
{
|
||||
result = connector.searchWithAggregates(loggedInUser, contentAsString);
|
||||
break;
|
||||
}
|
||||
case TYPE_REINDEX:
|
||||
{
|
||||
var from = request.getParameter(TIME_FROM);
|
||||
if (from == 'undefined') from = JS_MIN_VALUE;
|
||||
var to = request.getParameter(TIME_TO);
|
||||
if (to == 'undefined') to = JS_MAX_VALUE;
|
||||
result = connector.reIndex(loggedInUser, tableName, from, to);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
result = '{ "status": "Failed", "statusCode": "500", "message": "Unidentified operation" }';
|
||||
}
|
||||
if (result != null) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("value of result: " + result);
|
||||
log.debug("status code: " + result.getstatusCode())
|
||||
}
|
||||
|
||||
var statusCode = result.getStatusCode();
|
||||
var status = result.getStatus();
|
||||
var message = result.getMessage();
|
||||
response.status = statusCode;
|
||||
var finalResult = {
|
||||
status: status,
|
||||
message: message
|
||||
};
|
||||
print(finalResult);
|
||||
}
|
||||
} else {
|
||||
print('{ "status": "Failed", "statusCode": "500", "message": "AnalyticsCachedWebServiceConnector is unavailable" }');
|
||||
}
|
||||
|
||||
}());
|
||||
%>
|
@ -0,0 +1,286 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
var CONSTANTS = {
|
||||
webAppName: 'outputui',
|
||||
urlSeperator: '/',
|
||||
urlGetParameter : '?lastUpdatedTime=',
|
||||
urlQueryStringBegin : '?',
|
||||
tenantUrlAttribute: 't',
|
||||
urlUnsecureTransportHttp : 'http://',
|
||||
urlUnsecureTransportWebsocket : 'ws://',
|
||||
urlSecureTransportWebsocket : 'wss://',
|
||||
urlSecureTransportHttp : 'https://',
|
||||
colon : ':',
|
||||
defaultIntervalTime : 10 * 1000,
|
||||
defaultUserDomain : 'carbon.super',
|
||||
defaultHostName : 'localhost',
|
||||
defaultNonsecurePortNumber : '9763',
|
||||
defaultSecurePortNumber : '9443',
|
||||
defaultMode : 'AUTO',
|
||||
processModeHTTP : 'HTTP',
|
||||
processModeWebSocket : 'WEBSOCKET',
|
||||
processModeAuto : 'AUTO',
|
||||
domain : 'carbon.super',
|
||||
numThousand : 1000,
|
||||
websocketTimeAppender : 400,
|
||||
secureMode : 'SECURED'
|
||||
};
|
||||
|
||||
|
||||
var websocket = null;
|
||||
var webSocketUrl;
|
||||
var httpUrl;
|
||||
var cepHostName;
|
||||
var cepPortNumber;
|
||||
var isErrorOccured = false;
|
||||
var lastUpdatedtime = -1;
|
||||
var polingInterval;
|
||||
var stream;
|
||||
var streamVersion;
|
||||
var firstPollingAttempt;
|
||||
var processMode;
|
||||
var onSuccessFunction;
|
||||
var onErrorFunction;
|
||||
var userDomainUrl = "";
|
||||
var terminateWebsocketInstance = false;
|
||||
var pollingContinue = true;
|
||||
var transportToBeUsedHttp;
|
||||
var transportToBeUsedWebsocket;
|
||||
|
||||
function subscribe(streamName,version,intervalTime,domain,
|
||||
listeningFuncSuccessData,listeningFuncErrorData,
|
||||
cepHost,cepPort,mode,secureMode, queryParams){
|
||||
|
||||
stopPollingProcesses();
|
||||
stream = streamName;
|
||||
streamVersion = version;
|
||||
onSuccessFunction = listeningFuncSuccessData;
|
||||
onErrorFunction = listeningFuncErrorData;
|
||||
|
||||
if(secureMode == CONSTANTS.secureMode){
|
||||
transportToBeUsedHttp = CONSTANTS.urlSecureTransportHttp;
|
||||
transportToBeUsedWebsocket = CONSTANTS.urlSecureTransportWebsocket;
|
||||
} else {
|
||||
transportToBeUsedHttp = CONSTANTS.urlUnsecureTransportHttp;
|
||||
transportToBeUsedWebsocket = CONSTANTS.urlUnsecureTransportWebsocket;
|
||||
}
|
||||
|
||||
if(intervalTime == null || intervalTime == ""){
|
||||
polingInterval = CONSTANTS.defaultIntervalTime;
|
||||
} else{
|
||||
polingInterval = intervalTime * CONSTANTS.numThousand;
|
||||
}
|
||||
|
||||
if(domain == null || domain == ""){
|
||||
domain = CONSTANTS.defaultUserDomain;
|
||||
}
|
||||
|
||||
if(cepHost == null || cepHost == ""){
|
||||
cepHostName = CONSTANTS.defaultHostName;
|
||||
} else{
|
||||
cepHostName = cepHost;
|
||||
}
|
||||
|
||||
if(cepPort == null || cepPort == ""){
|
||||
if(secureMode == CONSTANTS.secureMode){
|
||||
cepPortNumber = CONSTANTS.defaultSecurePortNumber;
|
||||
} else{
|
||||
cepPortNumber = CONSTANTS.defaultNonsecurePortNumber;
|
||||
}
|
||||
} else{
|
||||
cepPortNumber = cepPort;
|
||||
}
|
||||
|
||||
if(mode == null || mode == ""){
|
||||
processMode = CONSTANTS.defaultMode;
|
||||
} else{
|
||||
processMode = mode;
|
||||
}
|
||||
|
||||
if(domain != CONSTANTS.domain){
|
||||
userDomainUrl = CONSTANTS.tenantUrlAttribute + CONSTANTS.urlSeperator + domain + CONSTANTS.urlSeperator;
|
||||
|
||||
}
|
||||
|
||||
if (queryParams == null) {
|
||||
queryParams = "";
|
||||
} else if (queryParams != "") {
|
||||
queryParams = CONSTANTS.urlQueryStringBegin + queryParams;
|
||||
}
|
||||
|
||||
webSocketUrl = transportToBeUsedWebsocket + cepHostName + CONSTANTS.colon + cepPortNumber +
|
||||
CONSTANTS.urlSeperator + CONSTANTS.webAppName+ CONSTANTS.urlSeperator + userDomainUrl + stream +
|
||||
CONSTANTS.urlSeperator + streamVersion + queryParams;
|
||||
|
||||
|
||||
if(processMode == CONSTANTS.processModeHTTP){
|
||||
firstPollingAttempt = true;
|
||||
pollingContinue = true;
|
||||
startPoll();
|
||||
} else{
|
||||
initializeWebSocket(webSocketUrl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializing Web Socket
|
||||
*/
|
||||
function initializeWebSocket(webSocketUrl){
|
||||
websocket = new WebSocket(webSocketUrl);
|
||||
websocket.onopen = webSocketOnOpen;
|
||||
websocket.onmessage = webSocketOnMessage;
|
||||
websocket.onclose = webSocketOnClose;
|
||||
websocket.onerror = webSocketOnError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Web socket On Open
|
||||
*/
|
||||
|
||||
var webSocketOnOpen = function () {
|
||||
// alert("Successfully connected to "+webSocketUrl);
|
||||
//onErrorFunction("Successfully connected to URL:" + webSocketUrl + "\n");
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* On server sends a message
|
||||
*/
|
||||
var webSocketOnMessage = function (evt) {
|
||||
var event = evt.data;
|
||||
var array = JSON.parse(event);
|
||||
constructPayload(array);
|
||||
};
|
||||
|
||||
/**
|
||||
* On server close
|
||||
*/
|
||||
var webSocketOnClose =function (e) {
|
||||
|
||||
if(isErrorOccured){
|
||||
if(processMode != CONSTANTS.processModeWebSocket){
|
||||
firstPollingAttempt = true;
|
||||
pollingContinue = true;
|
||||
startPoll();
|
||||
}
|
||||
} else{
|
||||
if(!terminateWebsocketInstance){
|
||||
waitForSocketConnection(websocket);
|
||||
} else{
|
||||
terminateWebsocketInstance = false;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* On server Error
|
||||
*/
|
||||
var webSocketOnError = function (err) {
|
||||
var error = "Error: Cannot connect to Websocket URL:" + webSocketUrl + " .Hence closing the connection!";
|
||||
|
||||
onErrorFunction(error);
|
||||
isErrorOccured = true;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Gracefully increments the connection retry
|
||||
*/
|
||||
var waitTime = CONSTANTS.numThousand;
|
||||
function waitForSocketConnection(socket, callback){
|
||||
setTimeout(
|
||||
function () {
|
||||
if (socket.readyState === 1) {
|
||||
initializeWebSocket(webSocketUrl);
|
||||
console.log("Connection is made");
|
||||
if(callback != null){
|
||||
callback();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
websocket = new WebSocket(webSocketUrl);
|
||||
waitTime += CONSTANTS.websocketTimeAppender;
|
||||
waitForSocketConnection(websocket, callback);
|
||||
}
|
||||
}, waitTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Polling to retrieve events from http request periodically
|
||||
*/
|
||||
function startPoll(){
|
||||
|
||||
(function poll(){
|
||||
setTimeout(function(){
|
||||
httpUrl = transportToBeUsedHttp + cepHostName + CONSTANTS.colon + cepPortNumber + CONSTANTS.urlSeperator
|
||||
+ CONSTANTS.webAppName + CONSTANTS.urlSeperator + userDomainUrl + stream + CONSTANTS.urlSeperator +
|
||||
streamVersion + CONSTANTS.urlGetParameter + lastUpdatedtime;
|
||||
|
||||
$.getJSON(httpUrl, function(responseText) {
|
||||
if(firstPollingAttempt){
|
||||
/*var data = $("textarea#idConsole").val();
|
||||
$("textarea#idConsole").val(data + "Successfully connected to HTTP.");*/
|
||||
firstPollingAttempt = false;
|
||||
}
|
||||
|
||||
var eventList = $.parseJSON(responseText.events);
|
||||
if(eventList.length != 0){
|
||||
lastUpdatedtime = responseText.lastEventTime;
|
||||
for(var i=0;i<eventList.length;i++){
|
||||
var arr = eventList[i];
|
||||
constructPayload(arr);
|
||||
}
|
||||
}
|
||||
if(pollingContinue){
|
||||
startPoll();
|
||||
}
|
||||
})
|
||||
.fail(function(errorData) {
|
||||
var errorData = JSON.parse(errorData.responseText);
|
||||
onErrorFunction(errorData.error);
|
||||
});
|
||||
}, polingInterval);
|
||||
})()
|
||||
}
|
||||
|
||||
function stopPollingProcesses(){
|
||||
|
||||
//stopping the Websocket
|
||||
if(websocket != null){
|
||||
terminateWebsocketInstance = true;
|
||||
websocket.onclose;
|
||||
}
|
||||
//stopping the HTTPS Request
|
||||
pollingContinue = false;
|
||||
|
||||
}
|
||||
|
||||
function constructPayload(eventsArray){
|
||||
|
||||
var streamId = stream + CONSTANTS.colon + streamVersion;
|
||||
var twoDimentionalArray = [eventsArray];
|
||||
onSuccessFunction(streamId,twoDimentionalArray);
|
||||
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,29 @@
|
||||
/*!
|
||||
* d3.geomap
|
||||
* https://github.com/yaph/d3-geomap/blob/master/LICENSE
|
||||
* MIT licensed
|
||||
* Copyright (C) 2015 by Ramiro Gómez (http://ramiro.org/)
|
||||
*/
|
||||
text {
|
||||
fill: #333;
|
||||
font-size: 12px; }
|
||||
|
||||
.background {
|
||||
fill: none;
|
||||
pointer-events: all; }
|
||||
|
||||
.unit {
|
||||
cursor: pointer;
|
||||
fill: #ccc;
|
||||
stroke: #000;
|
||||
stroke-width: 0.4px; }
|
||||
|
||||
.legend-bg {
|
||||
fill: #fff;
|
||||
fill-opacity: 0.8; }
|
||||
|
||||
.legend-bar {
|
||||
stroke: #333;
|
||||
stroke-width: 1px; }
|
||||
|
||||
/*# sourceMappingURL=geomap.css.map */
|
@ -0,0 +1,80 @@
|
||||
#rect {
|
||||
fill: none;
|
||||
stroke: rgb(0, 0, 0);
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
#rectCurve {
|
||||
fill: none;
|
||||
stroke: rgb(0, 0, 0);
|
||||
stroke-width: 0.5;
|
||||
}
|
||||
|
||||
.axis path,
|
||||
.axis line {
|
||||
fill: none;
|
||||
shape-rendering: crispEdges;
|
||||
stroke: grey;
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.line {
|
||||
fill: none;
|
||||
stroke: steelblue;
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
|
||||
.label{
|
||||
font-size: 16.844px !important;
|
||||
}
|
||||
|
||||
/* arc tween shit*/
|
||||
.background {
|
||||
fill: #FFFFFF;
|
||||
fill-opacity: 0.01;
|
||||
}
|
||||
|
||||
.component {
|
||||
fill: #e1e1e1;
|
||||
}
|
||||
|
||||
.component .label {
|
||||
font-family: Myriad, "Helvetic Neue", Helvetica, Arial;
|
||||
text-anchor: middle;
|
||||
fill: #0000FF;
|
||||
}
|
||||
|
||||
.arc {
|
||||
stroke-weight:0.1;
|
||||
fill: #4e8fff;
|
||||
}
|
||||
|
||||
|
||||
.arc2 {
|
||||
stroke-weight:0.1;
|
||||
fill: #3660b0;
|
||||
}
|
||||
|
||||
|
||||
.label {
|
||||
font-family: Myriad, "Helvetic Neue", Helvetica, Arial;
|
||||
text-anchor: middle;
|
||||
}
|
||||
|
||||
.labelArc {
|
||||
font-family: Myriad, "Helvetic Neue", Helvetica, Arial;
|
||||
text-anchor: middle;
|
||||
fill: #0000FF;
|
||||
}
|
||||
|
||||
.tooltipClass {
|
||||
background-color: #e5f2ff;
|
||||
padding: 4px 8px;
|
||||
|
||||
}
|
||||
.tooltipClass p{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
{"id":"IoTServerTemperatureStats","title":"IoTServerTemperatureStats","type":"gadget","thumbnail":"local://images/gadgetIcon.png","data":{"url":"local://store/carbon.super/gadget/IoTServerTemperatureStats/index.xml"}}
|
@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<Module>
|
||||
<ModulePrefs title="Bar Chart"
|
||||
author="WSO2 Gadget Server"
|
||||
height="230"
|
||||
scrolling="true"
|
||||
tags="charts,bar,visualization,data"
|
||||
description="A generic Bar Chart gadget, that takes a json datasource as an input. It can be configured to fetch data in defined intervals. This gadget can be used to create dashboards with statistical data. This gadget can be reused as an iframe in any web page as it is self contained.">
|
||||
</ModulePrefs>
|
||||
<UserPref name="dataSource"
|
||||
display_name="Data Source"
|
||||
default_value="/portal/gadgets/bar-chart/datasource/dataFile4.jag">
|
||||
</UserPref>
|
||||
<!--UserPref name="options"
|
||||
display_name="Chart Options"
|
||||
default_value="/portal/gadgets/bar-chart/js/options-bar.js">
|
||||
</UserPref-->
|
||||
<UserPref name="updateGraph"
|
||||
display_name="Update Interval (s)"
|
||||
default_value="No">
|
||||
</UserPref>
|
||||
<Content type="html">
|
||||
<![CDATA[
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Bar Chart</title>
|
||||
<link href="css/flot-graph.css" rel="stylesheet" type="text/css">
|
||||
<link href="css/igviz.css" rel="stylesheet" type="text/css">
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="css/d3.geomap.css" rel="stylesheet" type="text/css">
|
||||
<script language="javascript" type="text/javascript" src="js/excanvas.min.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/jquery.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/topojson.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/d3.min.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/vega.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/VizGrammar.min.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/gadgetconf.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/outputAdapterUiLibrary.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/main.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="placeholder" class="demo-placeholder" style="height:90%"></div>
|
||||
<script language="javascript" type="text/javascript">
|
||||
if(jQuery("#placeholder").html() == ""){
|
||||
jQuery("#placeholder").append('<div id="noChart"><table><tr><td style="padding:30px 20px 0px 20px"><img src="../../portal/images/noEvents.png" align="left" style="width:24;height:24"/></td><td><br/><b><p><br/> Data is not available for plotting</p></b></td></tr><tr><td></td><td><p>The chart will be loaded once the dashboard receives events</p><td/></tr></table></div>');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
]]>
|
||||
</Content>
|
||||
</Module>
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,48 @@
|
||||
if(navigator.appVersion.indexOf("MSIE")!=-1&&parseFloat(navigator.appVersion.split("MSIE")[1])<=8&&!document.createElement("canvas").getContext)(function(){var m=Math;var mr=m.round;var ms=m.sin;var mc=m.cos;var abs=m.abs;var sqrt=m.sqrt;var Z=10;var Z2=Z/2;var IE_VERSION=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];function getContext(){return this.context_||(this.context_=new CanvasRenderingContext2D_(this))}var slice=Array.prototype.slice;function bind(f,obj,var_args){var a=slice.call(arguments,
|
||||
2);return function(){return f.apply(obj,a.concat(slice.call(arguments)))}}function encodeHtmlAttribute(s){return String(s).replace(/&/g,"&").replace(/"/g,""")}function addNamespace(doc,prefix,urn){if(!doc.namespaces[prefix])doc.namespaces.add(prefix,urn,"#default#VML")}function addNamespacesAndStylesheet(doc){addNamespace(doc,"g_vml_","urn:schemas-microsoft-com:vml");addNamespace(doc,"g_o_","urn:schemas-microsoft-com:office:office");if(!doc.styleSheets["ex_canvas_"]){var ss=doc.createStyleSheet();
|
||||
ss.owningElement.id="ex_canvas_";ss.cssText="canvas{display:inline-block;overflow:hidden;"+"text-align:left;width:300px;height:150px}"}}addNamespacesAndStylesheet(document);var G_vmlCanvasManager_={init:function(opt_doc){var doc=opt_doc||document;doc.createElement("canvas");doc.attachEvent("onreadystatechange",bind(this.init_,this,doc))},init_:function(doc){var els=doc.getElementsByTagName("canvas");for(var i=0;i<els.length;i++)this.initElement(els[i])},initElement:function(el){if(!el.getContext){el.getContext=
|
||||
getContext;addNamespacesAndStylesheet(el.ownerDocument);el.innerHTML="";el.attachEvent("onpropertychange",onPropertyChange);el.attachEvent("onresize",onResize);var attrs=el.attributes;if(attrs.width&&attrs.width.specified)el.style.width=attrs.width.nodeValue+"px";else el.width=el.clientWidth;if(attrs.height&&attrs.height.specified)el.style.height=attrs.height.nodeValue+"px";else el.height=el.clientHeight}return el}};function onPropertyChange(e){var el=e.srcElement;switch(e.propertyName){case "width":el.getContext().clearRect();
|
||||
el.style.width=el.attributes.width.nodeValue+"px";el.firstChild.style.width=el.clientWidth+"px";break;case "height":el.getContext().clearRect();el.style.height=el.attributes.height.nodeValue+"px";el.firstChild.style.height=el.clientHeight+"px";break}}function onResize(e){var el=e.srcElement;if(el.firstChild){el.firstChild.style.width=el.clientWidth+"px";el.firstChild.style.height=el.clientHeight+"px"}}G_vmlCanvasManager_.init();var decToHex=[];for(var i=0;i<16;i++)for(var j=0;j<16;j++)decToHex[i*
|
||||
16+j]=i.toString(16)+j.toString(16);function createMatrixIdentity(){return[[1,0,0],[0,1,0],[0,0,1]]}function matrixMultiply(m1,m2){var result=createMatrixIdentity();for(var x=0;x<3;x++)for(var y=0;y<3;y++){var sum=0;for(var z=0;z<3;z++)sum+=m1[x][z]*m2[z][y];result[x][y]=sum}return result}function copyState(o1,o2){o2.fillStyle=o1.fillStyle;o2.lineCap=o1.lineCap;o2.lineJoin=o1.lineJoin;o2.lineWidth=o1.lineWidth;o2.miterLimit=o1.miterLimit;o2.shadowBlur=o1.shadowBlur;o2.shadowColor=o1.shadowColor;o2.shadowOffsetX=
|
||||
o1.shadowOffsetX;o2.shadowOffsetY=o1.shadowOffsetY;o2.strokeStyle=o1.strokeStyle;o2.globalAlpha=o1.globalAlpha;o2.font=o1.font;o2.textAlign=o1.textAlign;o2.textBaseline=o1.textBaseline;o2.arcScaleX_=o1.arcScaleX_;o2.arcScaleY_=o1.arcScaleY_;o2.lineScale_=o1.lineScale_}var colorData={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",
|
||||
chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",
|
||||
darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",grey:"#808080",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",
|
||||
lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",
|
||||
mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",oldlace:"#FDF5E6",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",
|
||||
salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",whitesmoke:"#F5F5F5",yellowgreen:"#9ACD32"};function getRgbHslContent(styleString){var start=styleString.indexOf("(",3);var end=styleString.indexOf(")",start+1);var parts=
|
||||
styleString.substring(start+1,end).split(",");if(parts.length!=4||styleString.charAt(3)!="a")parts[3]=1;return parts}function percent(s){return parseFloat(s)/100}function clamp(v,min,max){return Math.min(max,Math.max(min,v))}function hslToRgb(parts){var r,g,b,h,s,l;h=parseFloat(parts[0])/360%360;if(h<0)h++;s=clamp(percent(parts[1]),0,1);l=clamp(percent(parts[2]),0,1);if(s==0)r=g=b=l;else{var q=l<0.5?l*(1+s):l+s-l*s;var p=2*l-q;r=hueToRgb(p,q,h+1/3);g=hueToRgb(p,q,h);b=hueToRgb(p,q,h-1/3)}return"#"+
|
||||
decToHex[Math.floor(r*255)]+decToHex[Math.floor(g*255)]+decToHex[Math.floor(b*255)]}function hueToRgb(m1,m2,h){if(h<0)h++;if(h>1)h--;if(6*h<1)return m1+(m2-m1)*6*h;else if(2*h<1)return m2;else if(3*h<2)return m1+(m2-m1)*(2/3-h)*6;else return m1}var processStyleCache={};function processStyle(styleString){if(styleString in processStyleCache)return processStyleCache[styleString];var str,alpha=1;styleString=String(styleString);if(styleString.charAt(0)=="#")str=styleString;else if(/^rgb/.test(styleString)){var parts=
|
||||
getRgbHslContent(styleString);var str="#",n;for(var i=0;i<3;i++){if(parts[i].indexOf("%")!=-1)n=Math.floor(percent(parts[i])*255);else n=+parts[i];str+=decToHex[clamp(n,0,255)]}alpha=+parts[3]}else if(/^hsl/.test(styleString)){var parts=getRgbHslContent(styleString);str=hslToRgb(parts);alpha=parts[3]}else str=colorData[styleString]||styleString;return processStyleCache[styleString]={color:str,alpha:alpha}}var DEFAULT_STYLE={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};
|
||||
var fontStyleCache={};function processFontStyle(styleString){if(fontStyleCache[styleString])return fontStyleCache[styleString];var el=document.createElement("div");var style=el.style;try{style.font=styleString}catch(ex){}return fontStyleCache[styleString]={style:style.fontStyle||DEFAULT_STYLE.style,variant:style.fontVariant||DEFAULT_STYLE.variant,weight:style.fontWeight||DEFAULT_STYLE.weight,size:style.fontSize||DEFAULT_STYLE.size,family:style.fontFamily||DEFAULT_STYLE.family}}function getComputedStyle(style,
|
||||
element){var computedStyle={};for(var p in style)computedStyle[p]=style[p];var canvasFontSize=parseFloat(element.currentStyle.fontSize),fontSize=parseFloat(style.size);if(typeof style.size=="number")computedStyle.size=style.size;else if(style.size.indexOf("px")!=-1)computedStyle.size=fontSize;else if(style.size.indexOf("em")!=-1)computedStyle.size=canvasFontSize*fontSize;else if(style.size.indexOf("%")!=-1)computedStyle.size=canvasFontSize/100*fontSize;else if(style.size.indexOf("pt")!=-1)computedStyle.size=
|
||||
fontSize/0.75;else computedStyle.size=canvasFontSize;computedStyle.size*=0.981;return computedStyle}function buildStyle(style){return style.style+" "+style.variant+" "+style.weight+" "+style.size+"px "+style.family}var lineCapMap={"butt":"flat","round":"round"};function processLineCap(lineCap){return lineCapMap[lineCap]||"square"}function CanvasRenderingContext2D_(canvasElement){this.m_=createMatrixIdentity();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle=
|
||||
"#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=Z*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=canvasElement;var cssText="width:"+canvasElement.clientWidth+"px;height:"+canvasElement.clientHeight+"px;overflow:hidden;position:absolute";var el=canvasElement.ownerDocument.createElement("div");el.style.cssText=cssText;canvasElement.appendChild(el);var overlayEl=el.cloneNode(false);overlayEl.style.backgroundColor=
|
||||
"red";overlayEl.style.filter="alpha(opacity=0)";canvasElement.appendChild(overlayEl);this.element_=el;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var contextPrototype=CanvasRenderingContext2D_.prototype;contextPrototype.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};contextPrototype.beginPath=function(){this.currentPath_=[]};contextPrototype.moveTo=function(aX,aY){var p=getCoords(this,aX,aY);this.currentPath_.push({type:"moveTo",
|
||||
x:p.x,y:p.y});this.currentX_=p.x;this.currentY_=p.y};contextPrototype.lineTo=function(aX,aY){var p=getCoords(this,aX,aY);this.currentPath_.push({type:"lineTo",x:p.x,y:p.y});this.currentX_=p.x;this.currentY_=p.y};contextPrototype.bezierCurveTo=function(aCP1x,aCP1y,aCP2x,aCP2y,aX,aY){var p=getCoords(this,aX,aY);var cp1=getCoords(this,aCP1x,aCP1y);var cp2=getCoords(this,aCP2x,aCP2y);bezierCurveTo(this,cp1,cp2,p)};function bezierCurveTo(self,cp1,cp2,p){self.currentPath_.push({type:"bezierCurveTo",cp1x:cp1.x,
|
||||
cp1y:cp1.y,cp2x:cp2.x,cp2y:cp2.y,x:p.x,y:p.y});self.currentX_=p.x;self.currentY_=p.y}contextPrototype.quadraticCurveTo=function(aCPx,aCPy,aX,aY){var cp=getCoords(this,aCPx,aCPy);var p=getCoords(this,aX,aY);var cp1={x:this.currentX_+2/3*(cp.x-this.currentX_),y:this.currentY_+2/3*(cp.y-this.currentY_)};var cp2={x:cp1.x+(p.x-this.currentX_)/3,y:cp1.y+(p.y-this.currentY_)/3};bezierCurveTo(this,cp1,cp2,p)};contextPrototype.arc=function(aX,aY,aRadius,aStartAngle,aEndAngle,aClockwise){aRadius*=Z;var arcType=
|
||||
aClockwise?"at":"wa";var xStart=aX+mc(aStartAngle)*aRadius-Z2;var yStart=aY+ms(aStartAngle)*aRadius-Z2;var xEnd=aX+mc(aEndAngle)*aRadius-Z2;var yEnd=aY+ms(aEndAngle)*aRadius-Z2;if(xStart==xEnd&&!aClockwise)xStart+=0.125;var p=getCoords(this,aX,aY);var pStart=getCoords(this,xStart,yStart);var pEnd=getCoords(this,xEnd,yEnd);this.currentPath_.push({type:arcType,x:p.x,y:p.y,radius:aRadius,xStart:pStart.x,yStart:pStart.y,xEnd:pEnd.x,yEnd:pEnd.y})};contextPrototype.rect=function(aX,aY,aWidth,aHeight){this.moveTo(aX,
|
||||
aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath()};contextPrototype.strokeRect=function(aX,aY,aWidth,aHeight){var oldPath=this.currentPath_;this.beginPath();this.moveTo(aX,aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.stroke();this.currentPath_=oldPath};contextPrototype.fillRect=function(aX,aY,aWidth,aHeight){var oldPath=this.currentPath_;this.beginPath();this.moveTo(aX,aY);
|
||||
this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.fill();this.currentPath_=oldPath};contextPrototype.createLinearGradient=function(aX0,aY0,aX1,aY1){var gradient=new CanvasGradient_("gradient");gradient.x0_=aX0;gradient.y0_=aY0;gradient.x1_=aX1;gradient.y1_=aY1;return gradient};contextPrototype.createRadialGradient=function(aX0,aY0,aR0,aX1,aY1,aR1){var gradient=new CanvasGradient_("gradientradial");gradient.x0_=aX0;gradient.y0_=aY0;gradient.r0_=
|
||||
aR0;gradient.x1_=aX1;gradient.y1_=aY1;gradient.r1_=aR1;return gradient};contextPrototype.drawImage=function(image,var_args){var dx,dy,dw,dh,sx,sy,sw,sh;var oldRuntimeWidth=image.runtimeStyle.width;var oldRuntimeHeight=image.runtimeStyle.height;image.runtimeStyle.width="auto";image.runtimeStyle.height="auto";var w=image.width;var h=image.height;image.runtimeStyle.width=oldRuntimeWidth;image.runtimeStyle.height=oldRuntimeHeight;if(arguments.length==3){dx=arguments[1];dy=arguments[2];sx=sy=0;sw=dw=w;
|
||||
sh=dh=h}else if(arguments.length==5){dx=arguments[1];dy=arguments[2];dw=arguments[3];dh=arguments[4];sx=sy=0;sw=w;sh=h}else if(arguments.length==9){sx=arguments[1];sy=arguments[2];sw=arguments[3];sh=arguments[4];dx=arguments[5];dy=arguments[6];dw=arguments[7];dh=arguments[8]}else throw Error("Invalid number of arguments");var d=getCoords(this,dx,dy);var w2=sw/2;var h2=sh/2;var vmlStr=[];var W=10;var H=10;vmlStr.push(" <g_vml_:group",' coordsize="',Z*W,",",Z*H,'"',' coordorigin="0,0"',' style="width:',
|
||||
W,"px;height:",H,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]||this.m_[1][1]!=1||this.m_[1][0]){var filter=[];filter.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",mr(d.x/Z),",","Dy=",mr(d.y/Z),"");var max=d;var c2=getCoords(this,dx+dw,dy);var c3=getCoords(this,dx,dy+dh);var c4=getCoords(this,dx+dw,dy+dh);max.x=m.max(max.x,c2.x,c3.x,c4.x);max.y=m.max(max.y,c2.y,c3.y,c4.y);vmlStr.push("padding:0 ",mr(max.x/Z),"px ",mr(max.y/
|
||||
Z),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",filter.join(""),", sizingmethod='clip');")}else vmlStr.push("top:",mr(d.y/Z),"px;left:",mr(d.x/Z),"px;");vmlStr.push(' ">','<g_vml_:image src="',image.src,'"',' style="width:',Z*dw,"px;"," height:",Z*dh,'px"',' cropleft="',sx/w,'"',' croptop="',sy/h,'"',' cropright="',(w-sx-sw)/w,'"',' cropbottom="',(h-sy-sh)/h,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",vmlStr.join(""))};contextPrototype.stroke=function(aFill){var W=
|
||||
10;var H=10;var chunkSize=5E3;var min={x:null,y:null};var max={x:null,y:null};for(var j=0;j<this.currentPath_.length;j+=chunkSize){var lineStr=[];var lineOpen=false;lineStr.push("<g_vml_:shape",' filled="',!!aFill,'"',' style="position:absolute;width:',W,"px;height:",H,'px;"',' coordorigin="0,0"',' coordsize="',Z*W,",",Z*H,'"',' stroked="',!aFill,'"',' path="');var newSeq=false;for(var i=j;i<Math.min(j+chunkSize,this.currentPath_.length);i++){if(i%chunkSize==0&&i>0)lineStr.push(" m ",mr(this.currentPath_[i-
|
||||
1].x),",",mr(this.currentPath_[i-1].y));var p=this.currentPath_[i];var c;switch(p.type){case "moveTo":c=p;lineStr.push(" m ",mr(p.x),",",mr(p.y));break;case "lineTo":lineStr.push(" l ",mr(p.x),",",mr(p.y));break;case "close":lineStr.push(" x ");p=null;break;case "bezierCurveTo":lineStr.push(" c ",mr(p.cp1x),",",mr(p.cp1y),",",mr(p.cp2x),",",mr(p.cp2y),",",mr(p.x),",",mr(p.y));break;case "at":case "wa":lineStr.push(" ",p.type," ",mr(p.x-this.arcScaleX_*p.radius),",",mr(p.y-this.arcScaleY_*p.radius),
|
||||
" ",mr(p.x+this.arcScaleX_*p.radius),",",mr(p.y+this.arcScaleY_*p.radius)," ",mr(p.xStart),",",mr(p.yStart)," ",mr(p.xEnd),",",mr(p.yEnd));break}if(p){if(min.x==null||p.x<min.x)min.x=p.x;if(max.x==null||p.x>max.x)max.x=p.x;if(min.y==null||p.y<min.y)min.y=p.y;if(max.y==null||p.y>max.y)max.y=p.y}}lineStr.push(' ">');if(!aFill)appendStroke(this,lineStr);else appendFill(this,lineStr,min,max);lineStr.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",lineStr.join(""))}};function appendStroke(ctx,
|
||||
lineStr){var a=processStyle(ctx.strokeStyle);var color=a.color;var opacity=a.alpha*ctx.globalAlpha;var lineWidth=ctx.lineScale_*ctx.lineWidth;if(lineWidth<1)opacity*=lineWidth;lineStr.push("<g_vml_:stroke",' opacity="',opacity,'"',' joinstyle="',ctx.lineJoin,'"',' miterlimit="',ctx.miterLimit,'"',' endcap="',processLineCap(ctx.lineCap),'"',' weight="',lineWidth,'px"',' color="',color,'" />')}function appendFill(ctx,lineStr,min,max){var fillStyle=ctx.fillStyle;var arcScaleX=ctx.arcScaleX_;var arcScaleY=
|
||||
ctx.arcScaleY_;var width=max.x-min.x;var height=max.y-min.y;if(fillStyle instanceof CanvasGradient_){var angle=0;var focus={x:0,y:0};var shift=0;var expansion=1;if(fillStyle.type_=="gradient"){var x0=fillStyle.x0_/arcScaleX;var y0=fillStyle.y0_/arcScaleY;var x1=fillStyle.x1_/arcScaleX;var y1=fillStyle.y1_/arcScaleY;var p0=getCoords(ctx,x0,y0);var p1=getCoords(ctx,x1,y1);var dx=p1.x-p0.x;var dy=p1.y-p0.y;angle=Math.atan2(dx,dy)*180/Math.PI;if(angle<0)angle+=360;if(angle<1E-6)angle=0}else{var p0=getCoords(ctx,
|
||||
fillStyle.x0_,fillStyle.y0_);focus={x:(p0.x-min.x)/width,y:(p0.y-min.y)/height};width/=arcScaleX*Z;height/=arcScaleY*Z;var dimension=m.max(width,height);shift=2*fillStyle.r0_/dimension;expansion=2*fillStyle.r1_/dimension-shift}var stops=fillStyle.colors_;stops.sort(function(cs1,cs2){return cs1.offset-cs2.offset});var length=stops.length;var color1=stops[0].color;var color2=stops[length-1].color;var opacity1=stops[0].alpha*ctx.globalAlpha;var opacity2=stops[length-1].alpha*ctx.globalAlpha;var colors=
|
||||
[];for(var i=0;i<length;i++){var stop=stops[i];colors.push(stop.offset*expansion+shift+" "+stop.color)}lineStr.push('<g_vml_:fill type="',fillStyle.type_,'"',' method="none" focus="100%"',' color="',color1,'"',' color2="',color2,'"',' colors="',colors.join(","),'"',' opacity="',opacity2,'"',' g_o_:opacity2="',opacity1,'"',' angle="',angle,'"',' focusposition="',focus.x,",",focus.y,'" />')}else if(fillStyle instanceof CanvasPattern_){if(width&&height){var deltaLeft=-min.x;var deltaTop=-min.y;lineStr.push("<g_vml_:fill",
|
||||
' position="',deltaLeft/width*arcScaleX*arcScaleX,",",deltaTop/height*arcScaleY*arcScaleY,'"',' type="tile"',' src="',fillStyle.src_,'" />')}}else{var a=processStyle(ctx.fillStyle);var color=a.color;var opacity=a.alpha*ctx.globalAlpha;lineStr.push('<g_vml_:fill color="',color,'" opacity="',opacity,'" />')}}contextPrototype.fill=function(){this.stroke(true)};contextPrototype.closePath=function(){this.currentPath_.push({type:"close"})};function getCoords(ctx,aX,aY){var m=ctx.m_;return{x:Z*(aX*m[0][0]+
|
||||
aY*m[1][0]+m[2][0])-Z2,y:Z*(aX*m[0][1]+aY*m[1][1]+m[2][1])-Z2}}contextPrototype.save=function(){var o={};copyState(this,o);this.aStack_.push(o);this.mStack_.push(this.m_);this.m_=matrixMultiply(createMatrixIdentity(),this.m_)};contextPrototype.restore=function(){if(this.aStack_.length){copyState(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function matrixIsFinite(m){return isFinite(m[0][0])&&isFinite(m[0][1])&&isFinite(m[1][0])&&isFinite(m[1][1])&&isFinite(m[2][0])&&isFinite(m[2][1])}function setM(ctx,
|
||||
m,updateLineScale){if(!matrixIsFinite(m))return;ctx.m_=m;if(updateLineScale){var det=m[0][0]*m[1][1]-m[0][1]*m[1][0];ctx.lineScale_=sqrt(abs(det))}}contextPrototype.translate=function(aX,aY){var m1=[[1,0,0],[0,1,0],[aX,aY,1]];setM(this,matrixMultiply(m1,this.m_),false)};contextPrototype.rotate=function(aRot){var c=mc(aRot);var s=ms(aRot);var m1=[[c,s,0],[-s,c,0],[0,0,1]];setM(this,matrixMultiply(m1,this.m_),false)};contextPrototype.scale=function(aX,aY){this.arcScaleX_*=aX;this.arcScaleY_*=aY;var m1=
|
||||
[[aX,0,0],[0,aY,0],[0,0,1]];setM(this,matrixMultiply(m1,this.m_),true)};contextPrototype.transform=function(m11,m12,m21,m22,dx,dy){var m1=[[m11,m12,0],[m21,m22,0],[dx,dy,1]];setM(this,matrixMultiply(m1,this.m_),true)};contextPrototype.setTransform=function(m11,m12,m21,m22,dx,dy){var m=[[m11,m12,0],[m21,m22,0],[dx,dy,1]];setM(this,m,true)};contextPrototype.drawText_=function(text,x,y,maxWidth,stroke){var m=this.m_,delta=1E3,left=0,right=delta,offset={x:0,y:0},lineStr=[];var fontStyle=getComputedStyle(processFontStyle(this.font),
|
||||
this.element_);var fontStyleString=buildStyle(fontStyle);var elementStyle=this.element_.currentStyle;var textAlign=this.textAlign.toLowerCase();switch(textAlign){case "left":case "center":case "right":break;case "end":textAlign=elementStyle.direction=="ltr"?"right":"left";break;case "start":textAlign=elementStyle.direction=="rtl"?"right":"left";break;default:textAlign="left"}switch(this.textBaseline){case "hanging":case "top":offset.y=fontStyle.size/1.75;break;case "middle":break;default:case null:case "alphabetic":case "ideographic":case "bottom":offset.y=
|
||||
-fontStyle.size/2.25;break}switch(textAlign){case "right":left=delta;right=0.05;break;case "center":left=right=delta/2;break}var d=getCoords(this,x+offset.x,y+offset.y);lineStr.push('<g_vml_:line from="',-left,' 0" to="',right,' 0.05" ',' coordsize="100 100" coordorigin="0 0"',' filled="',!stroke,'" stroked="',!!stroke,'" style="position:absolute;width:1px;height:1px;">');if(stroke)appendStroke(this,lineStr);else appendFill(this,lineStr,{x:-left,y:0},{x:right,y:fontStyle.size});var skewM=m[0][0].toFixed(3)+
|
||||
","+m[1][0].toFixed(3)+","+m[0][1].toFixed(3)+","+m[1][1].toFixed(3)+",0,0";var skewOffset=mr(d.x/Z)+","+mr(d.y/Z);lineStr.push('<g_vml_:skew on="t" matrix="',skewM,'" ',' offset="',skewOffset,'" origin="',left,' 0" />','<g_vml_:path textpathok="true" />','<g_vml_:textpath on="true" string="',encodeHtmlAttribute(text),'" style="v-text-align:',textAlign,";font:",encodeHtmlAttribute(fontStyleString),'" /></g_vml_:line>');this.element_.insertAdjacentHTML("beforeEnd",lineStr.join(""))};contextPrototype.fillText=
|
||||
function(text,x,y,maxWidth){this.drawText_(text,x,y,maxWidth,false)};contextPrototype.strokeText=function(text,x,y,maxWidth){this.drawText_(text,x,y,maxWidth,true)};contextPrototype.measureText=function(text){if(!this.textMeasureEl_){var s='<span style="position:absolute;'+"top:-20000px;left:0;padding:0;margin:0;border:none;"+'white-space:pre;"></span>';this.element_.insertAdjacentHTML("beforeEnd",s);this.textMeasureEl_=this.element_.lastChild}var doc=this.element_.ownerDocument;this.textMeasureEl_.innerHTML=
|
||||
"";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(doc.createTextNode(text));return{width:this.textMeasureEl_.offsetWidth}};contextPrototype.clip=function(){};contextPrototype.arcTo=function(){};contextPrototype.createPattern=function(image,repetition){return new CanvasPattern_(image,repetition)};function CanvasGradient_(aType){this.type_=aType;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}CanvasGradient_.prototype.addColorStop=function(aOffset,
|
||||
aColor){aColor=processStyle(aColor);this.colors_.push({offset:aOffset,color:aColor.color,alpha:aColor.alpha})};function CanvasPattern_(image,repetition){assertImageIsValid(image);switch(repetition){case "repeat":case null:case "":this.repetition_="repeat";break;case "repeat-x":case "repeat-y":case "no-repeat":this.repetition_=repetition;break;default:throwException("SYNTAX_ERR")}this.src_=image.src;this.width_=image.width;this.height_=image.height}function throwException(s){throw new DOMException_(s);
|
||||
}function assertImageIsValid(img){if(!img||img.nodeType!=1||img.tagName!="IMG")throwException("TYPE_MISMATCH_ERR");if(img.readyState!="complete")throwException("INVALID_STATE_ERR")}function DOMException_(s){this.code=this[s];this.message=s+": DOM Exception "+this.code}var p=DOMException_.prototype=new Error;p.INDEX_SIZE_ERR=1;p.DOMSTRING_SIZE_ERR=2;p.HIERARCHY_REQUEST_ERR=3;p.WRONG_DOCUMENT_ERR=4;p.INVALID_CHARACTER_ERR=5;p.NO_DATA_ALLOWED_ERR=6;p.NO_MODIFICATION_ALLOWED_ERR=7;p.NOT_FOUND_ERR=8;p.NOT_SUPPORTED_ERR=
|
||||
9;p.INUSE_ATTRIBUTE_ERR=10;p.INVALID_STATE_ERR=11;p.SYNTAX_ERR=12;p.INVALID_MODIFICATION_ERR=13;p.NAMESPACE_ERR=14;p.INVALID_ACCESS_ERR=15;p.VALIDATION_ERR=16;p.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=G_vmlCanvasManager_;CanvasRenderingContext2D=CanvasRenderingContext2D_;CanvasGradient=CanvasGradient_;CanvasPattern=CanvasPattern_;DOMException=DOMException_})();
|
@ -0,0 +1,24 @@
|
||||
var gadgetConfig = {
|
||||
"id": "IoTServerTemperatureStats",
|
||||
"title": "IoTServerTemperatureStats",
|
||||
"datasource": "ORG_WSO2_IOT_DEVICES_TEMPERATURE",
|
||||
"type": "batch",
|
||||
"columns": [
|
||||
{"name": "TIMESTAMP", "type": "time"},
|
||||
{"name": "owner", "type": "string"},
|
||||
{"name": "deviceType", "type": "string"},
|
||||
{"name": "deviceId", "type": "string"},
|
||||
{"name": "time", "type": "long"},
|
||||
{"name": "temperature", "type": "float"}
|
||||
],
|
||||
"chartConfig": {
|
||||
"x": "time",
|
||||
"maxLength": "10",
|
||||
"padding": {"top": 30, "left": 45, "bottom": 38, "right": 55},
|
||||
"charts": [{"type": "line", "y": "temperature"}]
|
||||
},
|
||||
"domain": "carbon.super",
|
||||
/* timeFrom and timeTo need not be mentioned here since they will be automatically fetched
|
||||
if found in the QueryString of the URL */
|
||||
"params": ["owner", "deviceId"]
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,568 @@
|
||||
var datasource, type, columns, filter, maxUpdateValue, paramsToFilterBy;
|
||||
|
||||
var REFRESH_INTERVAL = 5000;
|
||||
|
||||
//this needs to be loaded from an autogenerated
|
||||
datasource = gadgetConfig.datasource;
|
||||
filter = gadgetConfig.filter;
|
||||
type = gadgetConfig.type;
|
||||
maxUpdateValue = gadgetConfig.maxUpdateValue;
|
||||
columns = gadgetConfig.columns;
|
||||
paramsToFilterBy = gadgetConfig.params;
|
||||
|
||||
var counter = 0;
|
||||
var TYPE_GET_BY_RANGE = 8;
|
||||
var TYPE_SEARCH = 13;
|
||||
var TYPE_SEARCH_COUNT = 14;
|
||||
|
||||
var TIME_FROM_STRING = "timeFrom";
|
||||
var TIME_TO_STRING = "timeTo";
|
||||
var UNIX_TIME_MAX_VALUE = "9007199254740992";
|
||||
var UNIX_TIME_MIN_VALUE = "-9007199254740992";
|
||||
var META_TAG = "meta_";
|
||||
var initialConfig, urlQueryParams, queryParamValPair, queryString;
|
||||
var dataTable, chart;
|
||||
|
||||
executeDataFetchForGadget();
|
||||
|
||||
/**
|
||||
* The main execution logic of the gadget is implemented in this function.
|
||||
*/
|
||||
function executeDataFetchForGadget() {
|
||||
var urlQueryString;
|
||||
|
||||
// fetch all queryParams from the URL.
|
||||
urlQueryParams = getAllQueryParamsFromURL();
|
||||
|
||||
// check if params config exists in the gadgetConf.
|
||||
if (typeof paramsToFilterBy != "undefined" && paramsToFilterBy.length != 0) {
|
||||
|
||||
if (urlQueryParams != null) {
|
||||
// get the values corresponding to the query "params" given in the gadgetConf
|
||||
queryParamValPair = getValuesOfQueryFilter();
|
||||
|
||||
// if at-least one of the given params in the conf are missing from the URL params then returns null.
|
||||
if (queryParamValPair == null) {
|
||||
console.log("Incomplete set of Query Params were found in the URL.");
|
||||
return;
|
||||
}
|
||||
|
||||
// construct the Lucene query string based on the params given in the gadget-conf
|
||||
// and the values parsed from the URL Query String.
|
||||
queryString = constructQueryString();
|
||||
|
||||
switch (type) {
|
||||
case "realtime":
|
||||
urlQueryString = decodeURIComponent(window.top.location.search.substring(1));
|
||||
//subscribe to websocket
|
||||
subscribe(
|
||||
datasource.split(":")[0], datasource.split(":")[1], '10', gadgetConfig.domain,
|
||||
onRealTimeEventSuccessRecieval, onRealTimeEventErrorRecieval,
|
||||
location.hostname, location.port, 'WEBSOCKET', "SECURED", urlQueryString);
|
||||
break;
|
||||
|
||||
case "batch":
|
||||
//load data immediately
|
||||
fetchDataOnQuery(fetchDataWithCount);
|
||||
// then start periodic polling
|
||||
setInterval(function () {
|
||||
fetchDataOnQuery(fetchDataWithCount);
|
||||
}, REFRESH_INTERVAL);
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
// if there are NO queryParams in the URL then exit.
|
||||
console.log("No Query Params were found in the URL to match the given filter-parameters.");
|
||||
}
|
||||
} else {
|
||||
// if no params to filter by are given in the gadget-conf, then fetch all info available
|
||||
// based on date range(if given).
|
||||
switch (type) {
|
||||
case "realtime":
|
||||
urlQueryString = decodeURIComponent(window.top.location.search.substring(1));
|
||||
//subscribe to websocket
|
||||
subscribe(datasource.split(":")[0], datasource.split(":")[1], '10', gadgetConfig.domain,
|
||||
onRealTimeEventSuccessRecieval, onRealTimeEventErrorRecieval, location.hostname, location.port,
|
||||
'WEBSOCKET', "SECURED", urlQueryString);
|
||||
break;
|
||||
|
||||
case "batch":
|
||||
//load data immediately
|
||||
fetchDataWithoutQuery(drawBatchChart);
|
||||
|
||||
// then start periodic polling
|
||||
setInterval(function () {
|
||||
fetchDataWithoutQuery(drawBatchChart);
|
||||
}, REFRESH_INTERVAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the page's URL Query-Params and returns them as an associative array.
|
||||
* @returns {*} an associative array containing the URL QueryParams and corresponding values.
|
||||
* If no such Query-Params exists then returns null.
|
||||
*/
|
||||
function getAllQueryParamsFromURL() {
|
||||
var queryParamList = [], qParam;
|
||||
var urlQueryString = decodeURIComponent(window.top.location.search.substring(1));
|
||||
if (urlQueryString) {
|
||||
var queryStringPairs = urlQueryString.split('&');
|
||||
for (var i = 0; i < queryStringPairs.length; i++) {
|
||||
qParam = queryStringPairs[i].split('=');
|
||||
queryParamList[qParam[0]] = qParam[1];
|
||||
}
|
||||
return queryParamList;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the values from the URL-QueryString corresponding to the given QueryParams in the gadget-conf file.
|
||||
* The parameters "timeTo" & "timeFrom" (if found in the query string) are added to the returned object regardless
|
||||
* of whether they are listed in the gadget-conf.
|
||||
* @returns {*} an associative array of the given params in the conf and corresponding value fetched from the
|
||||
* URL string.
|
||||
*/
|
||||
function getValuesOfQueryFilter() {
|
||||
var queryValues = [];
|
||||
|
||||
if (TIME_FROM_STRING in urlQueryParams) {
|
||||
queryValues[TIME_FROM_STRING] = urlQueryParams[TIME_FROM_STRING];
|
||||
}
|
||||
|
||||
if (TIME_TO_STRING in urlQueryParams) {
|
||||
queryValues[TIME_TO_STRING] = urlQueryParams[TIME_TO_STRING];
|
||||
}
|
||||
|
||||
for (var i = 0; i < paramsToFilterBy.length; i++) {
|
||||
var queryV = urlQueryParams[paramsToFilterBy[i]];
|
||||
|
||||
// if atleast one of the queryParams given in the gadgetConf is missing then return "null".
|
||||
if (typeof queryV != "undefined" && queryV != null && queryV != "") {
|
||||
queryValues[paramsToFilterBy[i]] = queryV;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return queryValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the Lucene Query String to be sent to DAS API.
|
||||
* @returns {string} a fully constructed query string from the params given in gadget-conf and
|
||||
* the query string of the URL.
|
||||
*/
|
||||
function constructQueryString() {
|
||||
var queryString = "'";
|
||||
for (var a = 0; a < paramsToFilterBy.length; a++) {
|
||||
if (queryString.length == 1) {
|
||||
queryString += META_TAG + paramsToFilterBy[a] + ":" + queryParamValPair[paramsToFilterBy[a]];
|
||||
} else {
|
||||
queryString += " AND " + META_TAG + paramsToFilterBy[a] + ":" + queryParamValPair[paramsToFilterBy[a]];
|
||||
}
|
||||
}
|
||||
|
||||
if (TIME_FROM_STRING in queryParamValPair && TIME_TO_STRING in queryParamValPair) {
|
||||
// both ends of the time-range (From What Date - To What Date) is given
|
||||
queryString += " AND " + META_TAG + "time:" +
|
||||
"[" + queryParamValPair[TIME_FROM_STRING] + " TO " + queryParamValPair[TIME_TO_STRING] + "]";
|
||||
|
||||
} else if (TIME_FROM_STRING in queryParamValPair && !(TIME_TO_STRING in queryParamValPair)) {
|
||||
// Only the start of the time-range (From What Date) is given
|
||||
queryString += " AND " + META_TAG + "time:" +
|
||||
"[" + queryParamValPair[TIME_FROM_STRING] + " TO " + UNIX_TIME_MAX_VALUE + "]";
|
||||
|
||||
} else if (!(TIME_FROM_STRING in queryParamValPair) && TIME_TO_STRING in queryParamValPair) {
|
||||
// Only the end of the time-range (To What Date) is given
|
||||
queryString += " AND " + META_TAG + "time:" +
|
||||
"[" + UNIX_TIME_MIN_VALUE + " TO " + queryParamValPair[TIME_TO_STRING] + "]";
|
||||
}
|
||||
//queryString += " AND meta_time:[1456467843079 TO 1456468494817]'";
|
||||
queryString += "'";
|
||||
return queryString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to fetch columns of the datasource provided for a Batch-Type Gadget.
|
||||
* @param table the name of the datasource table whose columns needs to be extracted.
|
||||
*/
|
||||
function getColumns(table) {
|
||||
console.log("Fetching table schema for table: " + table);
|
||||
var url = "/portal/apis/analytics?type=10&tableName=" + table;
|
||||
$.getJSON(url, function (data) {
|
||||
if (data) {
|
||||
columns = parseColumns(JSON.parse(data.message));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/** Constructs an associative array containing the columns and the corresponding data-type ("String", "Long", etc)
|
||||
* from the returned object as a result of the "getColumns" method above.
|
||||
* @param data the response object returned from the "getColumns(table)" call to the DAS API.
|
||||
* @returns {Array|*} an array containing the column names as keys and their type as values.
|
||||
*/
|
||||
function parseColumns(data) {
|
||||
if (data.columns) {
|
||||
var keys = Object.getOwnPropertyNames(data.columns);
|
||||
columns = keys.map(function (key, i) {
|
||||
return column = {
|
||||
name: key,
|
||||
type: data.columns[key].type
|
||||
};
|
||||
});
|
||||
return columns;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the initial call to the DAS APIs to get the count of all matching indexes based on a given query.
|
||||
* Upon receiving a response (count), a subsequent method is called to fetch the given "count" amount of data from
|
||||
* DAS that matches the query.
|
||||
* @param callback the subsequent method to be called using the "count" response value received from the API call.
|
||||
*/
|
||||
function fetchDataOnQuery(callback) {
|
||||
var request = {
|
||||
type: TYPE_SEARCH_COUNT, // DAS API type corresponding to fetching data-count for "query"
|
||||
tableName: datasource,
|
||||
query: queryString
|
||||
};
|
||||
$.ajax({
|
||||
url: "/portal/apis/analytics",
|
||||
method: "GET",
|
||||
data: request,
|
||||
contentType: "application/json",
|
||||
success: function (data) {
|
||||
if (callback != null) {
|
||||
callback(drawBatchChart, data.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an API call to the DAS to fetch the "count" number of data matching the queryString constructed from the
|
||||
* query-string and the param-list provided in the gadget-conf. The fetched data are passed into the provided
|
||||
* "callback" method which further processes and draws the chart against this data.
|
||||
* @param callback the method to which the fetched data are to be passed in for further processing.
|
||||
* @param totalCount the count of all matching data available against the queryString.
|
||||
*/
|
||||
function fetchDataWithCount(callback, totalCount) {
|
||||
var timeFrom = "undefined";
|
||||
var timeTo = "undefined";
|
||||
var request = {
|
||||
type: TYPE_SEARCH, // DAS API type corresponding to fetching data for "query"
|
||||
tableName: datasource,
|
||||
filter: filter,
|
||||
query: queryString,
|
||||
timeFrom: timeFrom,
|
||||
timeTo: timeTo,
|
||||
start: 0,
|
||||
count: totalCount
|
||||
};
|
||||
$.ajax({
|
||||
url: "/portal/apis/analytics",
|
||||
method: "GET",
|
||||
data: request,
|
||||
contentType: "application/json",
|
||||
success: function (data) {
|
||||
if (callback != null) {
|
||||
var sortedData = sortData(data.message);
|
||||
callback(makeRows(sortedData));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all data available in a datasource irrespective of any query filters. However, the API call incorporates
|
||||
* a data range to be submitted whilst fetching this info. If such date range related query strings
|
||||
* ("timeFrom" or "timeTo") are found in the URL, then they are used.
|
||||
* @param callback the method to which the fetched data are to be passed in for further processing.
|
||||
*/
|
||||
function fetchDataWithoutQuery(callback) {
|
||||
var timeFrom = "undefined";
|
||||
var timeTo = "undefined";
|
||||
|
||||
if (urlQueryParams != null) {
|
||||
if (TIME_FROM_STRING in urlQueryParams) {
|
||||
timeFrom = urlQueryParams[TIME_FROM_STRING];
|
||||
}
|
||||
|
||||
if (TIME_TO_STRING in urlQueryParams) {
|
||||
timeTo = urlQueryParams[TIME_TO_STRING];
|
||||
}
|
||||
}
|
||||
|
||||
var request = {
|
||||
type: TYPE_GET_BY_RANGE, // DAS API type corresponding to fetching data by date range.
|
||||
tableName: datasource,
|
||||
timeFrom: timeFrom,
|
||||
timeTo: timeTo,
|
||||
start: 0
|
||||
};
|
||||
$.ajax({
|
||||
url: "/portal/apis/analytics",
|
||||
method: "GET",
|
||||
data: request,
|
||||
contentType: "application/json",
|
||||
success: function (data) {
|
||||
if (callback != null) {
|
||||
callback(makeRows(JSON.parse(data.message)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a utility method to convert Unix-Timestamp values to Epoch Time
|
||||
* @param unix_timestamp the unix time to be converted
|
||||
* @returns {string} the formatted epoch-time of the given unix-timestamp
|
||||
*/
|
||||
function convertToEpoch(unix_timestamp) {
|
||||
// Create a new JavaScript Date object based on the timestamp
|
||||
// multiplied by 1000 so that the argument is in milliseconds, not seconds.
|
||||
var date = new Date(unix_timestamp * 1000);
|
||||
// Hours part from the timestamp
|
||||
var hours = date.getHours();
|
||||
// Minutes part from the timestamp
|
||||
var minutes = "0" + date.getMinutes();
|
||||
// Seconds part from the timestamp
|
||||
var seconds = "0" + date.getSeconds();
|
||||
|
||||
var thisDate = date.getDate();
|
||||
var thisMonth = date.getMonth();
|
||||
var thisYear = date.getUTCFullYear();
|
||||
|
||||
var formattedTime = hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
|
||||
|
||||
// Will display time in 10:30:23 format
|
||||
return (formattedTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the given data array according to the values of its "timestamp" key.
|
||||
* @param payload a JSON string with multiple data-arrays having a "timestamp" key-value pair.
|
||||
* @returns {*} JSON Object with multiple sorted by "timestamp"
|
||||
*/
|
||||
function sortData(payload) {
|
||||
var dataFromDAS = JSON.parse(payload);
|
||||
sortedData = dataFromDAS.sort(function (a, b) {
|
||||
return a.timestamp - b.timestamp;
|
||||
});
|
||||
return sortedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the values corresponding to the keys in the "columns" (either provided in the gadget-conf or fetched via the
|
||||
* "getColumns(table)" method) array from the data object passed in.
|
||||
* @param data a JSON Object containing multiple data values fetched from the datasource with column-name:value pairs.
|
||||
* @returns {Array} an array with objects that contain the columns from the fetched "columns" and their corresponding
|
||||
* values.
|
||||
*/
|
||||
function makeRows(data) {
|
||||
var rows = [];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var record = data[i];
|
||||
var keys = Object.getOwnPropertyNames(record.values);
|
||||
keys.push();
|
||||
|
||||
var row = columns.map(function (column, i) {
|
||||
var colName = column.name;
|
||||
var recordVal = record.values[colName];
|
||||
|
||||
if (typeof recordVal == 'undefined') {
|
||||
if (column.name.toUpperCase() === "TIMESTAMP" && (record.timestamp || record.TIMESTAMP)) {
|
||||
recordVal = record.timestamp;
|
||||
} else {
|
||||
recordVal = record.values[META_TAG + colName];
|
||||
}
|
||||
}
|
||||
return recordVal;
|
||||
});
|
||||
rows.push(row);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
function makeDataTable(data) {
|
||||
var dataTable = new igviz.DataTable();
|
||||
if (columns.length > 0) {
|
||||
columns.forEach(function (column, i) {
|
||||
var type = "N";
|
||||
if (column.type == "STRING" || column.type == "string") {
|
||||
type = "C";
|
||||
} else if (column.type == "TIME" || column.type == "time") {
|
||||
type = "T";
|
||||
}
|
||||
dataTable.addColumn(column.name, type);
|
||||
});
|
||||
}
|
||||
data.forEach(function (row, index) {
|
||||
for (var i = 0; i < row.length; i++) {
|
||||
if (dataTable.metadata.types[i] == "N") {
|
||||
data[index][i] = parseInt(data[index][i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
dataTable.addRows(data);
|
||||
return dataTable;
|
||||
}
|
||||
|
||||
function drawChart(data) {
|
||||
var dataTable = makeDataTable(data);
|
||||
gadgetConfig.chartConfig.width = $("#placeholder").width();
|
||||
gadgetConfig.chartConfig.height = $("#placeholder").height() - 65;
|
||||
var chartType = gadgetConfig.chartConfig.chartType;
|
||||
var xAxis = gadgetConfig.chartConfig.xAxis;
|
||||
jQuery("#noChart").html("");
|
||||
if (chartType === "bar" && dataTable.metadata.types[xAxis] === "N") {
|
||||
dataTable.metadata.types[xAxis] = "C";
|
||||
}
|
||||
|
||||
if (gadgetConfig.chartConfig.chartType === "table" || gadgetConfig.chartConfig.chartType === "singleNumber") {
|
||||
gadgetConfig.chartConfig.height = $("#placeholder").height();
|
||||
chart = igviz.draw("#placeholder", gadgetConfig.chartConfig, dataTable);
|
||||
chart.plot(dataTable.data);
|
||||
|
||||
} else {
|
||||
chart = igviz.setUp("#placeholder", gadgetConfig.chartConfig, dataTable);
|
||||
chart.setXAxis({
|
||||
"labelAngle": -35,
|
||||
"labelAlign": "right",
|
||||
"labelDy": 0,
|
||||
"labelDx": 0,
|
||||
"titleDy": 25
|
||||
})
|
||||
.setYAxis({
|
||||
"titleDy": -30
|
||||
});
|
||||
chart.plot(dataTable.data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//stuff required for realtime charting
|
||||
function onRealTimeEventSuccessRecieval(streamId, data) {
|
||||
drawRealtimeChart(data);
|
||||
}
|
||||
|
||||
function onRealTimeEventErrorRecieval(dataError) {
|
||||
console.log("Error occurred " + dataError);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the real-time chart based on the values in the data object passed in.
|
||||
* @param data an object containing all the column:value pair data
|
||||
*/
|
||||
function drawRealtimeChart(data) {
|
||||
if (chart == null) {
|
||||
jQuery("#noChart").html("");
|
||||
gadgetConfig.chartConfig.width = $("#placeholder").width() - 110;
|
||||
gadgetConfig.chartConfig.height = $("#placeholder").height() - 40;
|
||||
|
||||
if (gadgetConfig.chartConfig.charts[0].type == "map") {
|
||||
var mapType = gadgetConfig.chartConfig.charts[0].mapType;
|
||||
|
||||
if (mapType == "world") {
|
||||
gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/';
|
||||
gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/world/';
|
||||
} else if (mapType == "usa") {
|
||||
gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usaInfo/';
|
||||
gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usa/';
|
||||
} else if (mapType == "europe") {
|
||||
gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/';
|
||||
gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/europe/';
|
||||
}
|
||||
}
|
||||
|
||||
chart = new vizg(createDataTable(convertData(data)), gadgetConfig.chartConfig);
|
||||
chart.draw("#placeholder");
|
||||
} else {
|
||||
chart.insert(convertData(data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the batch-chart based on the values in the data object passed in.
|
||||
* @param data an object containing all the column:value pair data
|
||||
*/
|
||||
function drawBatchChart(data) {
|
||||
if (chart == null) {
|
||||
jQuery("#noChart").html("");
|
||||
gadgetConfig.chartConfig.width = $("#placeholder").width() - 110;
|
||||
gadgetConfig.chartConfig.height = $("#placeholder").height() - 40;
|
||||
|
||||
if (gadgetConfig.chartConfig.charts[0].type == "map") {
|
||||
var mapType = gadgetConfig.chartConfig.charts[0].mapType;
|
||||
|
||||
if (mapType == "world") {
|
||||
gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/';
|
||||
gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/world/';
|
||||
} else if (mapType == "usa") {
|
||||
gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usaInfo/';
|
||||
gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usa/';
|
||||
} else if (mapType == "europe") {
|
||||
gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/';
|
||||
gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/europe/';
|
||||
}
|
||||
}
|
||||
|
||||
initialConfig = JSON.parse(JSON.stringify(gadgetConfig.chartConfig));
|
||||
|
||||
} else {
|
||||
gadgetConfig.chartConfig = initialConfig;
|
||||
initialConfig = JSON.parse(JSON.stringify(gadgetConfig.chartConfig));
|
||||
}
|
||||
|
||||
chart = new vizg(createDataTable(convertData(data)), gadgetConfig.chartConfig);
|
||||
chart.draw("#placeholder");
|
||||
}
|
||||
|
||||
|
||||
function convertData(data) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
for (var x = 0; x < data[i].length; x++) {
|
||||
var type = gadgetConfig.columns[x]["type"].toUpperCase();
|
||||
if (type != "STRING" && type != "BOOLEAN") {
|
||||
data[i][x] = parseFloat(data[i][x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function createDataTable(data) {
|
||||
var names = [];
|
||||
var types = [];
|
||||
|
||||
for (var i = 0; i < gadgetConfig.columns.length; i++) {
|
||||
var name = gadgetConfig.columns[i]["name"];
|
||||
names.push(name);
|
||||
var type = columns[i]["type"].toUpperCase();
|
||||
|
||||
if (type === "INT" || type === "INTEGER" || type === "FLOAT" || type === "DOUBLE") {
|
||||
type = "linear";
|
||||
} else if (gadgetConfig.columns[i]["type"].toUpperCase() == "TIME" || name.toUpperCase() == "TIME") {
|
||||
type = "time";
|
||||
} else {
|
||||
type = "ordinal";
|
||||
}
|
||||
types.push(type);
|
||||
}
|
||||
|
||||
datatable = [
|
||||
{
|
||||
"metadata": {
|
||||
"names": names,
|
||||
"types": types
|
||||
},
|
||||
"data": data
|
||||
}
|
||||
];
|
||||
return datatable;
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,286 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
var CONSTANTS = {
|
||||
webAppName: 'outputui',
|
||||
urlSeperator: '/',
|
||||
urlGetParameter : '?lastUpdatedTime=',
|
||||
urlQueryStringBegin : '?',
|
||||
tenantUrlAttribute: 't',
|
||||
urlUnsecureTransportHttp : 'http://',
|
||||
urlUnsecureTransportWebsocket : 'ws://',
|
||||
urlSecureTransportWebsocket : 'wss://',
|
||||
urlSecureTransportHttp : 'https://',
|
||||
colon : ':',
|
||||
defaultIntervalTime : 10 * 1000,
|
||||
defaultUserDomain : 'carbon.super',
|
||||
defaultHostName : 'localhost',
|
||||
defaultNonsecurePortNumber : '9763',
|
||||
defaultSecurePortNumber : '9443',
|
||||
defaultMode : 'AUTO',
|
||||
processModeHTTP : 'HTTP',
|
||||
processModeWebSocket : 'WEBSOCKET',
|
||||
processModeAuto : 'AUTO',
|
||||
domain : 'carbon.super',
|
||||
numThousand : 1000,
|
||||
websocketTimeAppender : 400,
|
||||
secureMode : 'SECURED'
|
||||
};
|
||||
|
||||
|
||||
var websocket = null;
|
||||
var webSocketUrl;
|
||||
var httpUrl;
|
||||
var cepHostName;
|
||||
var cepPortNumber;
|
||||
var isErrorOccured = false;
|
||||
var lastUpdatedtime = -1;
|
||||
var polingInterval;
|
||||
var stream;
|
||||
var streamVersion;
|
||||
var firstPollingAttempt;
|
||||
var processMode;
|
||||
var onSuccessFunction;
|
||||
var onErrorFunction;
|
||||
var userDomainUrl = "";
|
||||
var terminateWebsocketInstance = false;
|
||||
var pollingContinue = true;
|
||||
var transportToBeUsedHttp;
|
||||
var transportToBeUsedWebsocket;
|
||||
|
||||
function subscribe(streamName,version,intervalTime,domain,
|
||||
listeningFuncSuccessData,listeningFuncErrorData,
|
||||
cepHost,cepPort,mode,secureMode, queryParams){
|
||||
|
||||
stopPollingProcesses();
|
||||
stream = streamName;
|
||||
streamVersion = version;
|
||||
onSuccessFunction = listeningFuncSuccessData;
|
||||
onErrorFunction = listeningFuncErrorData;
|
||||
|
||||
if(secureMode == CONSTANTS.secureMode){
|
||||
transportToBeUsedHttp = CONSTANTS.urlSecureTransportHttp;
|
||||
transportToBeUsedWebsocket = CONSTANTS.urlSecureTransportWebsocket;
|
||||
} else {
|
||||
transportToBeUsedHttp = CONSTANTS.urlUnsecureTransportHttp;
|
||||
transportToBeUsedWebsocket = CONSTANTS.urlUnsecureTransportWebsocket;
|
||||
}
|
||||
|
||||
if(intervalTime == null || intervalTime == ""){
|
||||
polingInterval = CONSTANTS.defaultIntervalTime;
|
||||
} else{
|
||||
polingInterval = intervalTime * CONSTANTS.numThousand;
|
||||
}
|
||||
|
||||
if(domain == null || domain == ""){
|
||||
domain = CONSTANTS.defaultUserDomain;
|
||||
}
|
||||
|
||||
if(cepHost == null || cepHost == ""){
|
||||
cepHostName = CONSTANTS.defaultHostName;
|
||||
} else{
|
||||
cepHostName = cepHost;
|
||||
}
|
||||
|
||||
if(cepPort == null || cepPort == ""){
|
||||
if(secureMode == CONSTANTS.secureMode){
|
||||
cepPortNumber = CONSTANTS.defaultSecurePortNumber;
|
||||
} else{
|
||||
cepPortNumber = CONSTANTS.defaultNonsecurePortNumber;
|
||||
}
|
||||
} else{
|
||||
cepPortNumber = cepPort;
|
||||
}
|
||||
|
||||
if(mode == null || mode == ""){
|
||||
processMode = CONSTANTS.defaultMode;
|
||||
} else{
|
||||
processMode = mode;
|
||||
}
|
||||
|
||||
if(domain != CONSTANTS.domain){
|
||||
userDomainUrl = CONSTANTS.tenantUrlAttribute + CONSTANTS.urlSeperator + domain + CONSTANTS.urlSeperator;
|
||||
|
||||
}
|
||||
|
||||
if (queryParams == null) {
|
||||
queryParams = "";
|
||||
} else if (queryParams != "") {
|
||||
queryParams = CONSTANTS.urlQueryStringBegin + queryParams;
|
||||
}
|
||||
|
||||
webSocketUrl = transportToBeUsedWebsocket + cepHostName + CONSTANTS.colon + cepPortNumber +
|
||||
CONSTANTS.urlSeperator + CONSTANTS.webAppName+ CONSTANTS.urlSeperator + userDomainUrl + stream +
|
||||
CONSTANTS.urlSeperator + streamVersion + queryParams;
|
||||
|
||||
|
||||
if(processMode == CONSTANTS.processModeHTTP){
|
||||
firstPollingAttempt = true;
|
||||
pollingContinue = true;
|
||||
startPoll();
|
||||
} else{
|
||||
initializeWebSocket(webSocketUrl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializing Web Socket
|
||||
*/
|
||||
function initializeWebSocket(webSocketUrl){
|
||||
websocket = new WebSocket(webSocketUrl);
|
||||
websocket.onopen = webSocketOnOpen;
|
||||
websocket.onmessage = webSocketOnMessage;
|
||||
websocket.onclose = webSocketOnClose;
|
||||
websocket.onerror = webSocketOnError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Web socket On Open
|
||||
*/
|
||||
|
||||
var webSocketOnOpen = function () {
|
||||
// alert("Successfully connected to "+webSocketUrl);
|
||||
//onErrorFunction("Successfully connected to URL:" + webSocketUrl + "\n");
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* On server sends a message
|
||||
*/
|
||||
var webSocketOnMessage = function (evt) {
|
||||
var event = evt.data;
|
||||
var array = JSON.parse(event);
|
||||
constructPayload(array);
|
||||
};
|
||||
|
||||
/**
|
||||
* On server close
|
||||
*/
|
||||
var webSocketOnClose =function (e) {
|
||||
|
||||
if(isErrorOccured){
|
||||
if(processMode != CONSTANTS.processModeWebSocket){
|
||||
firstPollingAttempt = true;
|
||||
pollingContinue = true;
|
||||
startPoll();
|
||||
}
|
||||
} else{
|
||||
if(!terminateWebsocketInstance){
|
||||
waitForSocketConnection(websocket);
|
||||
} else{
|
||||
terminateWebsocketInstance = false;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* On server Error
|
||||
*/
|
||||
var webSocketOnError = function (err) {
|
||||
var error = "Error: Cannot connect to Websocket URL:" + webSocketUrl + " .Hence closing the connection!";
|
||||
|
||||
onErrorFunction(error);
|
||||
isErrorOccured = true;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Gracefully increments the connection retry
|
||||
*/
|
||||
var waitTime = CONSTANTS.numThousand;
|
||||
function waitForSocketConnection(socket, callback){
|
||||
setTimeout(
|
||||
function () {
|
||||
if (socket.readyState === 1) {
|
||||
initializeWebSocket(webSocketUrl);
|
||||
console.log("Connection is made");
|
||||
if(callback != null){
|
||||
callback();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
websocket = new WebSocket(webSocketUrl);
|
||||
waitTime += CONSTANTS.websocketTimeAppender;
|
||||
waitForSocketConnection(websocket, callback);
|
||||
}
|
||||
}, waitTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Polling to retrieve events from http request periodically
|
||||
*/
|
||||
function startPoll(){
|
||||
|
||||
(function poll(){
|
||||
setTimeout(function(){
|
||||
httpUrl = transportToBeUsedHttp + cepHostName + CONSTANTS.colon + cepPortNumber + CONSTANTS.urlSeperator
|
||||
+ CONSTANTS.webAppName + CONSTANTS.urlSeperator + userDomainUrl + stream + CONSTANTS.urlSeperator +
|
||||
streamVersion + CONSTANTS.urlGetParameter + lastUpdatedtime;
|
||||
|
||||
$.getJSON(httpUrl, function(responseText) {
|
||||
if(firstPollingAttempt){
|
||||
/*var data = $("textarea#idConsole").val();
|
||||
$("textarea#idConsole").val(data + "Successfully connected to HTTP.");*/
|
||||
firstPollingAttempt = false;
|
||||
}
|
||||
|
||||
var eventList = $.parseJSON(responseText.events);
|
||||
if(eventList.length != 0){
|
||||
lastUpdatedtime = responseText.lastEventTime;
|
||||
for(var i=0;i<eventList.length;i++){
|
||||
var arr = eventList[i];
|
||||
constructPayload(arr);
|
||||
}
|
||||
}
|
||||
if(pollingContinue){
|
||||
startPoll();
|
||||
}
|
||||
})
|
||||
.fail(function(errorData) {
|
||||
var errorData = JSON.parse(errorData.responseText);
|
||||
onErrorFunction(errorData.error);
|
||||
});
|
||||
}, polingInterval);
|
||||
})()
|
||||
}
|
||||
|
||||
function stopPollingProcesses(){
|
||||
|
||||
//stopping the Websocket
|
||||
if(websocket != null){
|
||||
terminateWebsocketInstance = true;
|
||||
websocket.onclose;
|
||||
}
|
||||
//stopping the HTTPS Request
|
||||
pollingContinue = false;
|
||||
|
||||
}
|
||||
|
||||
function constructPayload(eventsArray){
|
||||
|
||||
var streamId = stream + CONSTANTS.colon + streamVersion;
|
||||
var twoDimentionalArray = [eventsArray];
|
||||
onSuccessFunction(streamId,twoDimentionalArray);
|
||||
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,29 @@
|
||||
/*!
|
||||
* d3.geomap
|
||||
* https://github.com/yaph/d3-geomap/blob/master/LICENSE
|
||||
* MIT licensed
|
||||
* Copyright (C) 2015 by Ramiro Gómez (http://ramiro.org/)
|
||||
*/
|
||||
text {
|
||||
fill: #333;
|
||||
font-size: 12px; }
|
||||
|
||||
.background {
|
||||
fill: none;
|
||||
pointer-events: all; }
|
||||
|
||||
.unit {
|
||||
cursor: pointer;
|
||||
fill: #ccc;
|
||||
stroke: #000;
|
||||
stroke-width: 0.4px; }
|
||||
|
||||
.legend-bg {
|
||||
fill: #fff;
|
||||
fill-opacity: 0.8; }
|
||||
|
||||
.legend-bar {
|
||||
stroke: #333;
|
||||
stroke-width: 1px; }
|
||||
|
||||
/*# sourceMappingURL=geomap.css.map */
|
@ -0,0 +1,80 @@
|
||||
#rect {
|
||||
fill: none;
|
||||
stroke: rgb(0, 0, 0);
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
#rectCurve {
|
||||
fill: none;
|
||||
stroke: rgb(0, 0, 0);
|
||||
stroke-width: 0.5;
|
||||
}
|
||||
|
||||
.axis path,
|
||||
.axis line {
|
||||
fill: none;
|
||||
shape-rendering: crispEdges;
|
||||
stroke: grey;
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.line {
|
||||
fill: none;
|
||||
stroke: steelblue;
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
|
||||
.label{
|
||||
font-size: 16.844px !important;
|
||||
}
|
||||
|
||||
/* arc tween shit*/
|
||||
.background {
|
||||
fill: #FFFFFF;
|
||||
fill-opacity: 0.01;
|
||||
}
|
||||
|
||||
.component {
|
||||
fill: #e1e1e1;
|
||||
}
|
||||
|
||||
.component .label {
|
||||
font-family: Myriad, "Helvetic Neue", Helvetica, Arial;
|
||||
text-anchor: middle;
|
||||
fill: #0000FF;
|
||||
}
|
||||
|
||||
.arc {
|
||||
stroke-weight:0.1;
|
||||
fill: #4e8fff;
|
||||
}
|
||||
|
||||
|
||||
.arc2 {
|
||||
stroke-weight:0.1;
|
||||
fill: #3660b0;
|
||||
}
|
||||
|
||||
|
||||
.label {
|
||||
font-family: Myriad, "Helvetic Neue", Helvetica, Arial;
|
||||
text-anchor: middle;
|
||||
}
|
||||
|
||||
.labelArc {
|
||||
font-family: Myriad, "Helvetic Neue", Helvetica, Arial;
|
||||
text-anchor: middle;
|
||||
fill: #0000FF;
|
||||
}
|
||||
|
||||
.tooltipClass {
|
||||
background-color: #e5f2ff;
|
||||
padding: 4px 8px;
|
||||
|
||||
}
|
||||
.tooltipClass p{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "TemperatureChart",
|
||||
"title": "TemperatureChart",
|
||||
"type": "gadget",
|
||||
"thumbnail": "local://images/gadgetIcon.png",
|
||||
"data": {
|
||||
"url": "local://store/carbon.super/gadget/TemperatureChart/index.xml"
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<Module>
|
||||
<ModulePrefs title="Bar Chart"
|
||||
author="WSO2 Gadget Server"
|
||||
height="230"
|
||||
scrolling="true"
|
||||
tags="charts,bar,visualization,data"
|
||||
description="A generic Bar Chart gadget, that takes a json datasource as an input. It can be configured to fetch data in defined intervals. This gadget can be used to create dashboards with statistical data. This gadget can be reused as an iframe in any web page as it is self contained.">
|
||||
</ModulePrefs>
|
||||
<UserPref name="dataSource"
|
||||
display_name="Data Source"
|
||||
default_value="/portal/gadgets/bar-chart/datasource/dataFile4.jag">
|
||||
</UserPref>
|
||||
<!--UserPref name="options"
|
||||
display_name="Chart Options"
|
||||
default_value="/portal/gadgets/bar-chart/js/options-bar.js">
|
||||
</UserPref-->
|
||||
<UserPref name="updateGraph"
|
||||
display_name="Update Interval (s)"
|
||||
default_value="No">
|
||||
</UserPref>
|
||||
<Content type="html">
|
||||
<![CDATA[
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Bar Chart</title>
|
||||
<link href="css/flot-graph.css" rel="stylesheet" type="text/css">
|
||||
<link href="css/igviz.css" rel="stylesheet" type="text/css">
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="css/d3.geomap.css" rel="stylesheet" type="text/css">
|
||||
<script language="javascript" type="text/javascript" src="js/excanvas.min.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/jquery.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/topojson.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/d3.min.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/vega.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/VizGrammar.min.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/gadgetconf.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/outputAdapterUiLibrary.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="js/main.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="placeholder" class="demo-placeholder" style="height:90%"></div>
|
||||
<script language="javascript" type="text/javascript">
|
||||
if(jQuery("#placeholder").html() == ""){
|
||||
jQuery("#placeholder").append('<div id="noChart"><table><tr><td style="padding:30px 20px 0px 20px"><img src="../../portal/images/noEvents.png" align="left" style="width:24;height:24"/></td><td><br/><b><p><br/> Data is not available for plotting</p></b></td></tr><tr><td></td><td><p>The chart will be loaded once the dashboard receives events</p><td/></tr></table></div>');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
]]>
|
||||
</Content>
|
||||
</Module>
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,48 @@
|
||||
if(navigator.appVersion.indexOf("MSIE")!=-1&&parseFloat(navigator.appVersion.split("MSIE")[1])<=8&&!document.createElement("canvas").getContext)(function(){var m=Math;var mr=m.round;var ms=m.sin;var mc=m.cos;var abs=m.abs;var sqrt=m.sqrt;var Z=10;var Z2=Z/2;var IE_VERSION=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];function getContext(){return this.context_||(this.context_=new CanvasRenderingContext2D_(this))}var slice=Array.prototype.slice;function bind(f,obj,var_args){var a=slice.call(arguments,
|
||||
2);return function(){return f.apply(obj,a.concat(slice.call(arguments)))}}function encodeHtmlAttribute(s){return String(s).replace(/&/g,"&").replace(/"/g,""")}function addNamespace(doc,prefix,urn){if(!doc.namespaces[prefix])doc.namespaces.add(prefix,urn,"#default#VML")}function addNamespacesAndStylesheet(doc){addNamespace(doc,"g_vml_","urn:schemas-microsoft-com:vml");addNamespace(doc,"g_o_","urn:schemas-microsoft-com:office:office");if(!doc.styleSheets["ex_canvas_"]){var ss=doc.createStyleSheet();
|
||||
ss.owningElement.id="ex_canvas_";ss.cssText="canvas{display:inline-block;overflow:hidden;"+"text-align:left;width:300px;height:150px}"}}addNamespacesAndStylesheet(document);var G_vmlCanvasManager_={init:function(opt_doc){var doc=opt_doc||document;doc.createElement("canvas");doc.attachEvent("onreadystatechange",bind(this.init_,this,doc))},init_:function(doc){var els=doc.getElementsByTagName("canvas");for(var i=0;i<els.length;i++)this.initElement(els[i])},initElement:function(el){if(!el.getContext){el.getContext=
|
||||
getContext;addNamespacesAndStylesheet(el.ownerDocument);el.innerHTML="";el.attachEvent("onpropertychange",onPropertyChange);el.attachEvent("onresize",onResize);var attrs=el.attributes;if(attrs.width&&attrs.width.specified)el.style.width=attrs.width.nodeValue+"px";else el.width=el.clientWidth;if(attrs.height&&attrs.height.specified)el.style.height=attrs.height.nodeValue+"px";else el.height=el.clientHeight}return el}};function onPropertyChange(e){var el=e.srcElement;switch(e.propertyName){case "width":el.getContext().clearRect();
|
||||
el.style.width=el.attributes.width.nodeValue+"px";el.firstChild.style.width=el.clientWidth+"px";break;case "height":el.getContext().clearRect();el.style.height=el.attributes.height.nodeValue+"px";el.firstChild.style.height=el.clientHeight+"px";break}}function onResize(e){var el=e.srcElement;if(el.firstChild){el.firstChild.style.width=el.clientWidth+"px";el.firstChild.style.height=el.clientHeight+"px"}}G_vmlCanvasManager_.init();var decToHex=[];for(var i=0;i<16;i++)for(var j=0;j<16;j++)decToHex[i*
|
||||
16+j]=i.toString(16)+j.toString(16);function createMatrixIdentity(){return[[1,0,0],[0,1,0],[0,0,1]]}function matrixMultiply(m1,m2){var result=createMatrixIdentity();for(var x=0;x<3;x++)for(var y=0;y<3;y++){var sum=0;for(var z=0;z<3;z++)sum+=m1[x][z]*m2[z][y];result[x][y]=sum}return result}function copyState(o1,o2){o2.fillStyle=o1.fillStyle;o2.lineCap=o1.lineCap;o2.lineJoin=o1.lineJoin;o2.lineWidth=o1.lineWidth;o2.miterLimit=o1.miterLimit;o2.shadowBlur=o1.shadowBlur;o2.shadowColor=o1.shadowColor;o2.shadowOffsetX=
|
||||
o1.shadowOffsetX;o2.shadowOffsetY=o1.shadowOffsetY;o2.strokeStyle=o1.strokeStyle;o2.globalAlpha=o1.globalAlpha;o2.font=o1.font;o2.textAlign=o1.textAlign;o2.textBaseline=o1.textBaseline;o2.arcScaleX_=o1.arcScaleX_;o2.arcScaleY_=o1.arcScaleY_;o2.lineScale_=o1.lineScale_}var colorData={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",
|
||||
chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",
|
||||
darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",grey:"#808080",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",
|
||||
lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",
|
||||
mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",oldlace:"#FDF5E6",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",
|
||||
salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",whitesmoke:"#F5F5F5",yellowgreen:"#9ACD32"};function getRgbHslContent(styleString){var start=styleString.indexOf("(",3);var end=styleString.indexOf(")",start+1);var parts=
|
||||
styleString.substring(start+1,end).split(",");if(parts.length!=4||styleString.charAt(3)!="a")parts[3]=1;return parts}function percent(s){return parseFloat(s)/100}function clamp(v,min,max){return Math.min(max,Math.max(min,v))}function hslToRgb(parts){var r,g,b,h,s,l;h=parseFloat(parts[0])/360%360;if(h<0)h++;s=clamp(percent(parts[1]),0,1);l=clamp(percent(parts[2]),0,1);if(s==0)r=g=b=l;else{var q=l<0.5?l*(1+s):l+s-l*s;var p=2*l-q;r=hueToRgb(p,q,h+1/3);g=hueToRgb(p,q,h);b=hueToRgb(p,q,h-1/3)}return"#"+
|
||||
decToHex[Math.floor(r*255)]+decToHex[Math.floor(g*255)]+decToHex[Math.floor(b*255)]}function hueToRgb(m1,m2,h){if(h<0)h++;if(h>1)h--;if(6*h<1)return m1+(m2-m1)*6*h;else if(2*h<1)return m2;else if(3*h<2)return m1+(m2-m1)*(2/3-h)*6;else return m1}var processStyleCache={};function processStyle(styleString){if(styleString in processStyleCache)return processStyleCache[styleString];var str,alpha=1;styleString=String(styleString);if(styleString.charAt(0)=="#")str=styleString;else if(/^rgb/.test(styleString)){var parts=
|
||||
getRgbHslContent(styleString);var str="#",n;for(var i=0;i<3;i++){if(parts[i].indexOf("%")!=-1)n=Math.floor(percent(parts[i])*255);else n=+parts[i];str+=decToHex[clamp(n,0,255)]}alpha=+parts[3]}else if(/^hsl/.test(styleString)){var parts=getRgbHslContent(styleString);str=hslToRgb(parts);alpha=parts[3]}else str=colorData[styleString]||styleString;return processStyleCache[styleString]={color:str,alpha:alpha}}var DEFAULT_STYLE={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};
|
||||
var fontStyleCache={};function processFontStyle(styleString){if(fontStyleCache[styleString])return fontStyleCache[styleString];var el=document.createElement("div");var style=el.style;try{style.font=styleString}catch(ex){}return fontStyleCache[styleString]={style:style.fontStyle||DEFAULT_STYLE.style,variant:style.fontVariant||DEFAULT_STYLE.variant,weight:style.fontWeight||DEFAULT_STYLE.weight,size:style.fontSize||DEFAULT_STYLE.size,family:style.fontFamily||DEFAULT_STYLE.family}}function getComputedStyle(style,
|
||||
element){var computedStyle={};for(var p in style)computedStyle[p]=style[p];var canvasFontSize=parseFloat(element.currentStyle.fontSize),fontSize=parseFloat(style.size);if(typeof style.size=="number")computedStyle.size=style.size;else if(style.size.indexOf("px")!=-1)computedStyle.size=fontSize;else if(style.size.indexOf("em")!=-1)computedStyle.size=canvasFontSize*fontSize;else if(style.size.indexOf("%")!=-1)computedStyle.size=canvasFontSize/100*fontSize;else if(style.size.indexOf("pt")!=-1)computedStyle.size=
|
||||
fontSize/0.75;else computedStyle.size=canvasFontSize;computedStyle.size*=0.981;return computedStyle}function buildStyle(style){return style.style+" "+style.variant+" "+style.weight+" "+style.size+"px "+style.family}var lineCapMap={"butt":"flat","round":"round"};function processLineCap(lineCap){return lineCapMap[lineCap]||"square"}function CanvasRenderingContext2D_(canvasElement){this.m_=createMatrixIdentity();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle=
|
||||
"#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=Z*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=canvasElement;var cssText="width:"+canvasElement.clientWidth+"px;height:"+canvasElement.clientHeight+"px;overflow:hidden;position:absolute";var el=canvasElement.ownerDocument.createElement("div");el.style.cssText=cssText;canvasElement.appendChild(el);var overlayEl=el.cloneNode(false);overlayEl.style.backgroundColor=
|
||||
"red";overlayEl.style.filter="alpha(opacity=0)";canvasElement.appendChild(overlayEl);this.element_=el;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var contextPrototype=CanvasRenderingContext2D_.prototype;contextPrototype.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};contextPrototype.beginPath=function(){this.currentPath_=[]};contextPrototype.moveTo=function(aX,aY){var p=getCoords(this,aX,aY);this.currentPath_.push({type:"moveTo",
|
||||
x:p.x,y:p.y});this.currentX_=p.x;this.currentY_=p.y};contextPrototype.lineTo=function(aX,aY){var p=getCoords(this,aX,aY);this.currentPath_.push({type:"lineTo",x:p.x,y:p.y});this.currentX_=p.x;this.currentY_=p.y};contextPrototype.bezierCurveTo=function(aCP1x,aCP1y,aCP2x,aCP2y,aX,aY){var p=getCoords(this,aX,aY);var cp1=getCoords(this,aCP1x,aCP1y);var cp2=getCoords(this,aCP2x,aCP2y);bezierCurveTo(this,cp1,cp2,p)};function bezierCurveTo(self,cp1,cp2,p){self.currentPath_.push({type:"bezierCurveTo",cp1x:cp1.x,
|
||||
cp1y:cp1.y,cp2x:cp2.x,cp2y:cp2.y,x:p.x,y:p.y});self.currentX_=p.x;self.currentY_=p.y}contextPrototype.quadraticCurveTo=function(aCPx,aCPy,aX,aY){var cp=getCoords(this,aCPx,aCPy);var p=getCoords(this,aX,aY);var cp1={x:this.currentX_+2/3*(cp.x-this.currentX_),y:this.currentY_+2/3*(cp.y-this.currentY_)};var cp2={x:cp1.x+(p.x-this.currentX_)/3,y:cp1.y+(p.y-this.currentY_)/3};bezierCurveTo(this,cp1,cp2,p)};contextPrototype.arc=function(aX,aY,aRadius,aStartAngle,aEndAngle,aClockwise){aRadius*=Z;var arcType=
|
||||
aClockwise?"at":"wa";var xStart=aX+mc(aStartAngle)*aRadius-Z2;var yStart=aY+ms(aStartAngle)*aRadius-Z2;var xEnd=aX+mc(aEndAngle)*aRadius-Z2;var yEnd=aY+ms(aEndAngle)*aRadius-Z2;if(xStart==xEnd&&!aClockwise)xStart+=0.125;var p=getCoords(this,aX,aY);var pStart=getCoords(this,xStart,yStart);var pEnd=getCoords(this,xEnd,yEnd);this.currentPath_.push({type:arcType,x:p.x,y:p.y,radius:aRadius,xStart:pStart.x,yStart:pStart.y,xEnd:pEnd.x,yEnd:pEnd.y})};contextPrototype.rect=function(aX,aY,aWidth,aHeight){this.moveTo(aX,
|
||||
aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath()};contextPrototype.strokeRect=function(aX,aY,aWidth,aHeight){var oldPath=this.currentPath_;this.beginPath();this.moveTo(aX,aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.stroke();this.currentPath_=oldPath};contextPrototype.fillRect=function(aX,aY,aWidth,aHeight){var oldPath=this.currentPath_;this.beginPath();this.moveTo(aX,aY);
|
||||
this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.fill();this.currentPath_=oldPath};contextPrototype.createLinearGradient=function(aX0,aY0,aX1,aY1){var gradient=new CanvasGradient_("gradient");gradient.x0_=aX0;gradient.y0_=aY0;gradient.x1_=aX1;gradient.y1_=aY1;return gradient};contextPrototype.createRadialGradient=function(aX0,aY0,aR0,aX1,aY1,aR1){var gradient=new CanvasGradient_("gradientradial");gradient.x0_=aX0;gradient.y0_=aY0;gradient.r0_=
|
||||
aR0;gradient.x1_=aX1;gradient.y1_=aY1;gradient.r1_=aR1;return gradient};contextPrototype.drawImage=function(image,var_args){var dx,dy,dw,dh,sx,sy,sw,sh;var oldRuntimeWidth=image.runtimeStyle.width;var oldRuntimeHeight=image.runtimeStyle.height;image.runtimeStyle.width="auto";image.runtimeStyle.height="auto";var w=image.width;var h=image.height;image.runtimeStyle.width=oldRuntimeWidth;image.runtimeStyle.height=oldRuntimeHeight;if(arguments.length==3){dx=arguments[1];dy=arguments[2];sx=sy=0;sw=dw=w;
|
||||
sh=dh=h}else if(arguments.length==5){dx=arguments[1];dy=arguments[2];dw=arguments[3];dh=arguments[4];sx=sy=0;sw=w;sh=h}else if(arguments.length==9){sx=arguments[1];sy=arguments[2];sw=arguments[3];sh=arguments[4];dx=arguments[5];dy=arguments[6];dw=arguments[7];dh=arguments[8]}else throw Error("Invalid number of arguments");var d=getCoords(this,dx,dy);var w2=sw/2;var h2=sh/2;var vmlStr=[];var W=10;var H=10;vmlStr.push(" <g_vml_:group",' coordsize="',Z*W,",",Z*H,'"',' coordorigin="0,0"',' style="width:',
|
||||
W,"px;height:",H,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]||this.m_[1][1]!=1||this.m_[1][0]){var filter=[];filter.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",mr(d.x/Z),",","Dy=",mr(d.y/Z),"");var max=d;var c2=getCoords(this,dx+dw,dy);var c3=getCoords(this,dx,dy+dh);var c4=getCoords(this,dx+dw,dy+dh);max.x=m.max(max.x,c2.x,c3.x,c4.x);max.y=m.max(max.y,c2.y,c3.y,c4.y);vmlStr.push("padding:0 ",mr(max.x/Z),"px ",mr(max.y/
|
||||
Z),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",filter.join(""),", sizingmethod='clip');")}else vmlStr.push("top:",mr(d.y/Z),"px;left:",mr(d.x/Z),"px;");vmlStr.push(' ">','<g_vml_:image src="',image.src,'"',' style="width:',Z*dw,"px;"," height:",Z*dh,'px"',' cropleft="',sx/w,'"',' croptop="',sy/h,'"',' cropright="',(w-sx-sw)/w,'"',' cropbottom="',(h-sy-sh)/h,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",vmlStr.join(""))};contextPrototype.stroke=function(aFill){var W=
|
||||
10;var H=10;var chunkSize=5E3;var min={x:null,y:null};var max={x:null,y:null};for(var j=0;j<this.currentPath_.length;j+=chunkSize){var lineStr=[];var lineOpen=false;lineStr.push("<g_vml_:shape",' filled="',!!aFill,'"',' style="position:absolute;width:',W,"px;height:",H,'px;"',' coordorigin="0,0"',' coordsize="',Z*W,",",Z*H,'"',' stroked="',!aFill,'"',' path="');var newSeq=false;for(var i=j;i<Math.min(j+chunkSize,this.currentPath_.length);i++){if(i%chunkSize==0&&i>0)lineStr.push(" m ",mr(this.currentPath_[i-
|
||||
1].x),",",mr(this.currentPath_[i-1].y));var p=this.currentPath_[i];var c;switch(p.type){case "moveTo":c=p;lineStr.push(" m ",mr(p.x),",",mr(p.y));break;case "lineTo":lineStr.push(" l ",mr(p.x),",",mr(p.y));break;case "close":lineStr.push(" x ");p=null;break;case "bezierCurveTo":lineStr.push(" c ",mr(p.cp1x),",",mr(p.cp1y),",",mr(p.cp2x),",",mr(p.cp2y),",",mr(p.x),",",mr(p.y));break;case "at":case "wa":lineStr.push(" ",p.type," ",mr(p.x-this.arcScaleX_*p.radius),",",mr(p.y-this.arcScaleY_*p.radius),
|
||||
" ",mr(p.x+this.arcScaleX_*p.radius),",",mr(p.y+this.arcScaleY_*p.radius)," ",mr(p.xStart),",",mr(p.yStart)," ",mr(p.xEnd),",",mr(p.yEnd));break}if(p){if(min.x==null||p.x<min.x)min.x=p.x;if(max.x==null||p.x>max.x)max.x=p.x;if(min.y==null||p.y<min.y)min.y=p.y;if(max.y==null||p.y>max.y)max.y=p.y}}lineStr.push(' ">');if(!aFill)appendStroke(this,lineStr);else appendFill(this,lineStr,min,max);lineStr.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",lineStr.join(""))}};function appendStroke(ctx,
|
||||
lineStr){var a=processStyle(ctx.strokeStyle);var color=a.color;var opacity=a.alpha*ctx.globalAlpha;var lineWidth=ctx.lineScale_*ctx.lineWidth;if(lineWidth<1)opacity*=lineWidth;lineStr.push("<g_vml_:stroke",' opacity="',opacity,'"',' joinstyle="',ctx.lineJoin,'"',' miterlimit="',ctx.miterLimit,'"',' endcap="',processLineCap(ctx.lineCap),'"',' weight="',lineWidth,'px"',' color="',color,'" />')}function appendFill(ctx,lineStr,min,max){var fillStyle=ctx.fillStyle;var arcScaleX=ctx.arcScaleX_;var arcScaleY=
|
||||
ctx.arcScaleY_;var width=max.x-min.x;var height=max.y-min.y;if(fillStyle instanceof CanvasGradient_){var angle=0;var focus={x:0,y:0};var shift=0;var expansion=1;if(fillStyle.type_=="gradient"){var x0=fillStyle.x0_/arcScaleX;var y0=fillStyle.y0_/arcScaleY;var x1=fillStyle.x1_/arcScaleX;var y1=fillStyle.y1_/arcScaleY;var p0=getCoords(ctx,x0,y0);var p1=getCoords(ctx,x1,y1);var dx=p1.x-p0.x;var dy=p1.y-p0.y;angle=Math.atan2(dx,dy)*180/Math.PI;if(angle<0)angle+=360;if(angle<1E-6)angle=0}else{var p0=getCoords(ctx,
|
||||
fillStyle.x0_,fillStyle.y0_);focus={x:(p0.x-min.x)/width,y:(p0.y-min.y)/height};width/=arcScaleX*Z;height/=arcScaleY*Z;var dimension=m.max(width,height);shift=2*fillStyle.r0_/dimension;expansion=2*fillStyle.r1_/dimension-shift}var stops=fillStyle.colors_;stops.sort(function(cs1,cs2){return cs1.offset-cs2.offset});var length=stops.length;var color1=stops[0].color;var color2=stops[length-1].color;var opacity1=stops[0].alpha*ctx.globalAlpha;var opacity2=stops[length-1].alpha*ctx.globalAlpha;var colors=
|
||||
[];for(var i=0;i<length;i++){var stop=stops[i];colors.push(stop.offset*expansion+shift+" "+stop.color)}lineStr.push('<g_vml_:fill type="',fillStyle.type_,'"',' method="none" focus="100%"',' color="',color1,'"',' color2="',color2,'"',' colors="',colors.join(","),'"',' opacity="',opacity2,'"',' g_o_:opacity2="',opacity1,'"',' angle="',angle,'"',' focusposition="',focus.x,",",focus.y,'" />')}else if(fillStyle instanceof CanvasPattern_){if(width&&height){var deltaLeft=-min.x;var deltaTop=-min.y;lineStr.push("<g_vml_:fill",
|
||||
' position="',deltaLeft/width*arcScaleX*arcScaleX,",",deltaTop/height*arcScaleY*arcScaleY,'"',' type="tile"',' src="',fillStyle.src_,'" />')}}else{var a=processStyle(ctx.fillStyle);var color=a.color;var opacity=a.alpha*ctx.globalAlpha;lineStr.push('<g_vml_:fill color="',color,'" opacity="',opacity,'" />')}}contextPrototype.fill=function(){this.stroke(true)};contextPrototype.closePath=function(){this.currentPath_.push({type:"close"})};function getCoords(ctx,aX,aY){var m=ctx.m_;return{x:Z*(aX*m[0][0]+
|
||||
aY*m[1][0]+m[2][0])-Z2,y:Z*(aX*m[0][1]+aY*m[1][1]+m[2][1])-Z2}}contextPrototype.save=function(){var o={};copyState(this,o);this.aStack_.push(o);this.mStack_.push(this.m_);this.m_=matrixMultiply(createMatrixIdentity(),this.m_)};contextPrototype.restore=function(){if(this.aStack_.length){copyState(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function matrixIsFinite(m){return isFinite(m[0][0])&&isFinite(m[0][1])&&isFinite(m[1][0])&&isFinite(m[1][1])&&isFinite(m[2][0])&&isFinite(m[2][1])}function setM(ctx,
|
||||
m,updateLineScale){if(!matrixIsFinite(m))return;ctx.m_=m;if(updateLineScale){var det=m[0][0]*m[1][1]-m[0][1]*m[1][0];ctx.lineScale_=sqrt(abs(det))}}contextPrototype.translate=function(aX,aY){var m1=[[1,0,0],[0,1,0],[aX,aY,1]];setM(this,matrixMultiply(m1,this.m_),false)};contextPrototype.rotate=function(aRot){var c=mc(aRot);var s=ms(aRot);var m1=[[c,s,0],[-s,c,0],[0,0,1]];setM(this,matrixMultiply(m1,this.m_),false)};contextPrototype.scale=function(aX,aY){this.arcScaleX_*=aX;this.arcScaleY_*=aY;var m1=
|
||||
[[aX,0,0],[0,aY,0],[0,0,1]];setM(this,matrixMultiply(m1,this.m_),true)};contextPrototype.transform=function(m11,m12,m21,m22,dx,dy){var m1=[[m11,m12,0],[m21,m22,0],[dx,dy,1]];setM(this,matrixMultiply(m1,this.m_),true)};contextPrototype.setTransform=function(m11,m12,m21,m22,dx,dy){var m=[[m11,m12,0],[m21,m22,0],[dx,dy,1]];setM(this,m,true)};contextPrototype.drawText_=function(text,x,y,maxWidth,stroke){var m=this.m_,delta=1E3,left=0,right=delta,offset={x:0,y:0},lineStr=[];var fontStyle=getComputedStyle(processFontStyle(this.font),
|
||||
this.element_);var fontStyleString=buildStyle(fontStyle);var elementStyle=this.element_.currentStyle;var textAlign=this.textAlign.toLowerCase();switch(textAlign){case "left":case "center":case "right":break;case "end":textAlign=elementStyle.direction=="ltr"?"right":"left";break;case "start":textAlign=elementStyle.direction=="rtl"?"right":"left";break;default:textAlign="left"}switch(this.textBaseline){case "hanging":case "top":offset.y=fontStyle.size/1.75;break;case "middle":break;default:case null:case "alphabetic":case "ideographic":case "bottom":offset.y=
|
||||
-fontStyle.size/2.25;break}switch(textAlign){case "right":left=delta;right=0.05;break;case "center":left=right=delta/2;break}var d=getCoords(this,x+offset.x,y+offset.y);lineStr.push('<g_vml_:line from="',-left,' 0" to="',right,' 0.05" ',' coordsize="100 100" coordorigin="0 0"',' filled="',!stroke,'" stroked="',!!stroke,'" style="position:absolute;width:1px;height:1px;">');if(stroke)appendStroke(this,lineStr);else appendFill(this,lineStr,{x:-left,y:0},{x:right,y:fontStyle.size});var skewM=m[0][0].toFixed(3)+
|
||||
","+m[1][0].toFixed(3)+","+m[0][1].toFixed(3)+","+m[1][1].toFixed(3)+",0,0";var skewOffset=mr(d.x/Z)+","+mr(d.y/Z);lineStr.push('<g_vml_:skew on="t" matrix="',skewM,'" ',' offset="',skewOffset,'" origin="',left,' 0" />','<g_vml_:path textpathok="true" />','<g_vml_:textpath on="true" string="',encodeHtmlAttribute(text),'" style="v-text-align:',textAlign,";font:",encodeHtmlAttribute(fontStyleString),'" /></g_vml_:line>');this.element_.insertAdjacentHTML("beforeEnd",lineStr.join(""))};contextPrototype.fillText=
|
||||
function(text,x,y,maxWidth){this.drawText_(text,x,y,maxWidth,false)};contextPrototype.strokeText=function(text,x,y,maxWidth){this.drawText_(text,x,y,maxWidth,true)};contextPrototype.measureText=function(text){if(!this.textMeasureEl_){var s='<span style="position:absolute;'+"top:-20000px;left:0;padding:0;margin:0;border:none;"+'white-space:pre;"></span>';this.element_.insertAdjacentHTML("beforeEnd",s);this.textMeasureEl_=this.element_.lastChild}var doc=this.element_.ownerDocument;this.textMeasureEl_.innerHTML=
|
||||
"";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(doc.createTextNode(text));return{width:this.textMeasureEl_.offsetWidth}};contextPrototype.clip=function(){};contextPrototype.arcTo=function(){};contextPrototype.createPattern=function(image,repetition){return new CanvasPattern_(image,repetition)};function CanvasGradient_(aType){this.type_=aType;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}CanvasGradient_.prototype.addColorStop=function(aOffset,
|
||||
aColor){aColor=processStyle(aColor);this.colors_.push({offset:aOffset,color:aColor.color,alpha:aColor.alpha})};function CanvasPattern_(image,repetition){assertImageIsValid(image);switch(repetition){case "repeat":case null:case "":this.repetition_="repeat";break;case "repeat-x":case "repeat-y":case "no-repeat":this.repetition_=repetition;break;default:throwException("SYNTAX_ERR")}this.src_=image.src;this.width_=image.width;this.height_=image.height}function throwException(s){throw new DOMException_(s);
|
||||
}function assertImageIsValid(img){if(!img||img.nodeType!=1||img.tagName!="IMG")throwException("TYPE_MISMATCH_ERR");if(img.readyState!="complete")throwException("INVALID_STATE_ERR")}function DOMException_(s){this.code=this[s];this.message=s+": DOM Exception "+this.code}var p=DOMException_.prototype=new Error;p.INDEX_SIZE_ERR=1;p.DOMSTRING_SIZE_ERR=2;p.HIERARCHY_REQUEST_ERR=3;p.WRONG_DOCUMENT_ERR=4;p.INVALID_CHARACTER_ERR=5;p.NO_DATA_ALLOWED_ERR=6;p.NO_MODIFICATION_ALLOWED_ERR=7;p.NOT_FOUND_ERR=8;p.NOT_SUPPORTED_ERR=
|
||||
9;p.INUSE_ATTRIBUTE_ERR=10;p.INVALID_STATE_ERR=11;p.SYNTAX_ERR=12;p.INVALID_MODIFICATION_ERR=13;p.NAMESPACE_ERR=14;p.INVALID_ACCESS_ERR=15;p.VALIDATION_ERR=16;p.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=G_vmlCanvasManager_;CanvasRenderingContext2D=CanvasRenderingContext2D_;CanvasGradient=CanvasGradient_;CanvasPattern=CanvasPattern_;DOMException=DOMException_})();
|
@ -0,0 +1,22 @@
|
||||
var gadgetConfig = {
|
||||
"id": "TemperatureChart",
|
||||
"title": "TemperatureChart",
|
||||
"datasource": "org.wso2.iot.devices.temperature:1.0.0",
|
||||
"type": "realtime",
|
||||
"columns": [
|
||||
{"name": "TIMESTAMP", "type": "time"},
|
||||
{"name": "owner", "type": "string"},
|
||||
{"name": "deviceType", "type": "string"},
|
||||
{"name": "deviceId", "type": "string"},
|
||||
{"name": "time", "type": "long"},
|
||||
{"name": "temperature", "type": "float"}
|
||||
],
|
||||
"chartConfig": {
|
||||
"x": "TIMESTAMP",
|
||||
"maxLength": "10",
|
||||
"padding": {"top": 30, "left": 45, "bottom": 38, "right": 55},
|
||||
"charts": [{"type": "line", "y": "temperature"}]
|
||||
},
|
||||
"domain": "carbon.super",
|
||||
"params": ["owner", "deviceId"]
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,568 @@
|
||||
var datasource, type, columns, filter, maxUpdateValue, paramsToFilterBy;
|
||||
|
||||
var REFRESH_INTERVAL = 5000;
|
||||
|
||||
//this needs to be loaded from an autogenerated
|
||||
datasource = gadgetConfig.datasource;
|
||||
filter = gadgetConfig.filter;
|
||||
type = gadgetConfig.type;
|
||||
maxUpdateValue = gadgetConfig.maxUpdateValue;
|
||||
columns = gadgetConfig.columns;
|
||||
paramsToFilterBy = gadgetConfig.params;
|
||||
|
||||
var counter = 0;
|
||||
var TYPE_GET_BY_RANGE = 8;
|
||||
var TYPE_SEARCH = 13;
|
||||
var TYPE_SEARCH_COUNT = 14;
|
||||
|
||||
var TIME_FROM_STRING = "timeFrom";
|
||||
var TIME_TO_STRING = "timeTo";
|
||||
var UNIX_TIME_MAX_VALUE = "9007199254740992";
|
||||
var UNIX_TIME_MIN_VALUE = "-9007199254740992";
|
||||
var META_TAG = "meta_";
|
||||
var initialConfig, urlQueryParams, queryParamValPair, queryString;
|
||||
var dataTable, chart;
|
||||
|
||||
executeDataFetchForGadget();
|
||||
|
||||
/**
|
||||
* The main execution logic of the gadget is implemented in this function.
|
||||
*/
|
||||
function executeDataFetchForGadget() {
|
||||
var urlQueryString;
|
||||
|
||||
// fetch all queryParams from the URL.
|
||||
urlQueryParams = getAllQueryParamsFromURL();
|
||||
|
||||
// check if params config exists in the gadgetConf.
|
||||
if (typeof paramsToFilterBy != "undefined" && paramsToFilterBy.length != 0) {
|
||||
|
||||
if (urlQueryParams != null) {
|
||||
// get the values corresponding to the query "params" given in the gadgetConf
|
||||
queryParamValPair = getValuesOfQueryFilter();
|
||||
|
||||
// if at-least one of the given params in the conf are missing from the URL params then returns null.
|
||||
if (queryParamValPair == null) {
|
||||
console.log("Incomplete set of Query Params were found in the URL.");
|
||||
return;
|
||||
}
|
||||
|
||||
// construct the Lucene query string based on the params given in the gadget-conf
|
||||
// and the values parsed from the URL Query String.
|
||||
queryString = constructQueryString();
|
||||
|
||||
switch (type) {
|
||||
case "realtime":
|
||||
urlQueryString = decodeURIComponent(window.top.location.search.substring(1));
|
||||
//subscribe to websocket
|
||||
subscribe(
|
||||
datasource.split(":")[0], datasource.split(":")[1], '10', gadgetConfig.domain,
|
||||
onRealTimeEventSuccessRecieval, onRealTimeEventErrorRecieval,
|
||||
location.hostname, location.port, 'WEBSOCKET', "SECURED", urlQueryString);
|
||||
break;
|
||||
|
||||
case "batch":
|
||||
//load data immediately
|
||||
fetchDataOnQuery(fetchDataWithCount);
|
||||
// then start periodic polling
|
||||
setInterval(function () {
|
||||
fetchDataOnQuery(fetchDataWithCount);
|
||||
}, REFRESH_INTERVAL);
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
// if there are NO queryParams in the URL then exit.
|
||||
console.log("No Query Params were found in the URL to match the given filter-parameters.");
|
||||
}
|
||||
} else {
|
||||
// if no params to filter by are given in the gadget-conf, then fetch all info available
|
||||
// based on date range(if given).
|
||||
switch (type) {
|
||||
case "realtime":
|
||||
urlQueryString = decodeURIComponent(window.top.location.search.substring(1));
|
||||
//subscribe to websocket
|
||||
subscribe(datasource.split(":")[0], datasource.split(":")[1], '10', gadgetConfig.domain,
|
||||
onRealTimeEventSuccessRecieval, onRealTimeEventErrorRecieval, location.hostname, location.port,
|
||||
'WEBSOCKET', "SECURED", urlQueryString);
|
||||
break;
|
||||
|
||||
case "batch":
|
||||
//load data immediately
|
||||
fetchDataWithoutQuery(drawBatchChart);
|
||||
|
||||
// then start periodic polling
|
||||
setInterval(function () {
|
||||
fetchDataWithoutQuery(drawBatchChart);
|
||||
}, REFRESH_INTERVAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the page's URL Query-Params and returns them as an associative array.
|
||||
* @returns {*} an associative array containing the URL QueryParams and corresponding values.
|
||||
* If no such Query-Params exists then returns null.
|
||||
*/
|
||||
function getAllQueryParamsFromURL() {
|
||||
var queryParamList = [], qParam;
|
||||
var urlQueryString = decodeURIComponent(window.top.location.search.substring(1));
|
||||
if (urlQueryString) {
|
||||
var queryStringPairs = urlQueryString.split('&');
|
||||
for (var i = 0; i < queryStringPairs.length; i++) {
|
||||
qParam = queryStringPairs[i].split('=');
|
||||
queryParamList[qParam[0]] = qParam[1];
|
||||
}
|
||||
return queryParamList;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the values from the URL-QueryString corresponding to the given QueryParams in the gadget-conf file.
|
||||
* The parameters "timeTo" & "timeFrom" (if found in the query string) are added to the returned object regardless
|
||||
* of whether they are listed in the gadget-conf.
|
||||
* @returns {*} an associative array of the given params in the conf and corresponding value fetched from the
|
||||
* URL string.
|
||||
*/
|
||||
function getValuesOfQueryFilter() {
|
||||
var queryValues = [];
|
||||
|
||||
if (TIME_FROM_STRING in urlQueryParams) {
|
||||
queryValues[TIME_FROM_STRING] = urlQueryParams[TIME_FROM_STRING];
|
||||
}
|
||||
|
||||
if (TIME_TO_STRING in urlQueryParams) {
|
||||
queryValues[TIME_TO_STRING] = urlQueryParams[TIME_TO_STRING];
|
||||
}
|
||||
|
||||
for (var i = 0; i < paramsToFilterBy.length; i++) {
|
||||
var queryV = urlQueryParams[paramsToFilterBy[i]];
|
||||
|
||||
// if atleast one of the queryParams given in the gadgetConf is missing then return "null".
|
||||
if (typeof queryV != "undefined" && queryV != null && queryV != "") {
|
||||
queryValues[paramsToFilterBy[i]] = queryV;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return queryValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the Lucene Query String to be sent to DAS API.
|
||||
* @returns {string} a fully constructed query string from the params given in gadget-conf and
|
||||
* the query string of the URL.
|
||||
*/
|
||||
function constructQueryString() {
|
||||
var queryString = "'";
|
||||
for (var a = 0; a < paramsToFilterBy.length; a++) {
|
||||
if (queryString.length == 1) {
|
||||
queryString += META_TAG + paramsToFilterBy[a] + ":" + queryParamValPair[paramsToFilterBy[a]];
|
||||
} else {
|
||||
queryString += " AND " + META_TAG + paramsToFilterBy[a] + ":" + queryParamValPair[paramsToFilterBy[a]];
|
||||
}
|
||||
}
|
||||
|
||||
if (TIME_FROM_STRING in queryParamValPair && TIME_TO_STRING in queryParamValPair) {
|
||||
// both ends of the time-range (From What Date - To What Date) is given
|
||||
queryString += " AND " + META_TAG + "time:" +
|
||||
"[" + queryParamValPair[TIME_FROM_STRING] + " TO " + queryParamValPair[TIME_TO_STRING] + "]";
|
||||
|
||||
} else if (TIME_FROM_STRING in queryParamValPair && !(TIME_TO_STRING in queryParamValPair)) {
|
||||
// Only the start of the time-range (From What Date) is given
|
||||
queryString += " AND " + META_TAG + "time:" +
|
||||
"[" + queryParamValPair[TIME_FROM_STRING] + " TO " + UNIX_TIME_MAX_VALUE + "]";
|
||||
|
||||
} else if (!(TIME_FROM_STRING in queryParamValPair) && TIME_TO_STRING in queryParamValPair) {
|
||||
// Only the end of the time-range (To What Date) is given
|
||||
queryString += " AND " + META_TAG + "time:" +
|
||||
"[" + UNIX_TIME_MIN_VALUE + " TO " + queryParamValPair[TIME_TO_STRING] + "]";
|
||||
}
|
||||
//queryString += " AND meta_time:[1456467843079 TO 1456468494817]'";
|
||||
queryString += "'";
|
||||
return queryString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to fetch columns of the datasource provided for a Batch-Type Gadget.
|
||||
* @param table the name of the datasource table whose columns needs to be extracted.
|
||||
*/
|
||||
function getColumns(table) {
|
||||
console.log("Fetching table schema for table: " + table);
|
||||
var url = "/portal/apis/analytics?type=10&tableName=" + table;
|
||||
$.getJSON(url, function (data) {
|
||||
if (data) {
|
||||
columns = parseColumns(JSON.parse(data.message));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/** Constructs an associative array containing the columns and the corresponding data-type ("String", "Long", etc)
|
||||
* from the returned object as a result of the "getColumns" method above.
|
||||
* @param data the response object returned from the "getColumns(table)" call to the DAS API.
|
||||
* @returns {Array|*} an array containing the column names as keys and their type as values.
|
||||
*/
|
||||
function parseColumns(data) {
|
||||
if (data.columns) {
|
||||
var keys = Object.getOwnPropertyNames(data.columns);
|
||||
columns = keys.map(function (key, i) {
|
||||
return column = {
|
||||
name: key,
|
||||
type: data.columns[key].type
|
||||
};
|
||||
});
|
||||
return columns;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the initial call to the DAS APIs to get the count of all matching indexes based on a given query.
|
||||
* Upon receiving a response (count), a subsequent method is called to fetch the given "count" amount of data from
|
||||
* DAS that matches the query.
|
||||
* @param callback the subsequent method to be called using the "count" response value received from the API call.
|
||||
*/
|
||||
function fetchDataOnQuery(callback) {
|
||||
var request = {
|
||||
type: TYPE_SEARCH_COUNT, // DAS API type corresponding to fetching data-count for "query"
|
||||
tableName: datasource,
|
||||
query: queryString
|
||||
};
|
||||
$.ajax({
|
||||
url: "/portal/apis/analytics",
|
||||
method: "GET",
|
||||
data: request,
|
||||
contentType: "application/json",
|
||||
success: function (data) {
|
||||
if (callback != null) {
|
||||
callback(drawBatchChart, data.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an API call to the DAS to fetch the "count" number of data matching the queryString constructed from the
|
||||
* query-string and the param-list provided in the gadget-conf. The fetched data are passed into the provided
|
||||
* "callback" method which further processes and draws the chart against this data.
|
||||
* @param callback the method to which the fetched data are to be passed in for further processing.
|
||||
* @param totalCount the count of all matching data available against the queryString.
|
||||
*/
|
||||
function fetchDataWithCount(callback, totalCount) {
|
||||
var timeFrom = "undefined";
|
||||
var timeTo = "undefined";
|
||||
var request = {
|
||||
type: TYPE_SEARCH, // DAS API type corresponding to fetching data for "query"
|
||||
tableName: datasource,
|
||||
filter: filter,
|
||||
query: queryString,
|
||||
timeFrom: timeFrom,
|
||||
timeTo: timeTo,
|
||||
start: 0,
|
||||
count: totalCount
|
||||
};
|
||||
$.ajax({
|
||||
url: "/portal/apis/analytics",
|
||||
method: "GET",
|
||||
data: request,
|
||||
contentType: "application/json",
|
||||
success: function (data) {
|
||||
if (callback != null) {
|
||||
var sortedData = sortData(data.message);
|
||||
callback(makeRows(sortedData));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all data available in a datasource irrespective of any query filters. However, the API call incorporates
|
||||
* a data range to be submitted whilst fetching this info. If such date range related query strings
|
||||
* ("timeFrom" or "timeTo") are found in the URL, then they are used.
|
||||
* @param callback the method to which the fetched data are to be passed in for further processing.
|
||||
*/
|
||||
function fetchDataWithoutQuery(callback) {
|
||||
var timeFrom = "undefined";
|
||||
var timeTo = "undefined";
|
||||
|
||||
if (urlQueryParams != null) {
|
||||
if (TIME_FROM_STRING in urlQueryParams) {
|
||||
timeFrom = urlQueryParams[TIME_FROM_STRING];
|
||||
}
|
||||
|
||||
if (TIME_TO_STRING in urlQueryParams) {
|
||||
timeTo = urlQueryParams[TIME_TO_STRING];
|
||||
}
|
||||
}
|
||||
|
||||
var request = {
|
||||
type: TYPE_GET_BY_RANGE, // DAS API type corresponding to fetching data by date range.
|
||||
tableName: datasource,
|
||||
timeFrom: timeFrom,
|
||||
timeTo: timeTo,
|
||||
start: 0
|
||||
};
|
||||
$.ajax({
|
||||
url: "/portal/apis/analytics",
|
||||
method: "GET",
|
||||
data: request,
|
||||
contentType: "application/json",
|
||||
success: function (data) {
|
||||
if (callback != null) {
|
||||
callback(makeRows(JSON.parse(data.message)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a utility method to convert Unix-Timestamp values to Epoch Time
|
||||
* @param unix_timestamp the unix time to be converted
|
||||
* @returns {string} the formatted epoch-time of the given unix-timestamp
|
||||
*/
|
||||
function convertToEpoch(unix_timestamp) {
|
||||
// Create a new JavaScript Date object based on the timestamp
|
||||
// multiplied by 1000 so that the argument is in milliseconds, not seconds.
|
||||
var date = new Date(unix_timestamp * 1000);
|
||||
// Hours part from the timestamp
|
||||
var hours = date.getHours();
|
||||
// Minutes part from the timestamp
|
||||
var minutes = "0" + date.getMinutes();
|
||||
// Seconds part from the timestamp
|
||||
var seconds = "0" + date.getSeconds();
|
||||
|
||||
var thisDate = date.getDate();
|
||||
var thisMonth = date.getMonth();
|
||||
var thisYear = date.getUTCFullYear();
|
||||
|
||||
var formattedTime = hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
|
||||
|
||||
// Will display time in 10:30:23 format
|
||||
return (formattedTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the given data array according to the values of its "timestamp" key.
|
||||
* @param payload a JSON string with multiple data-arrays having a "timestamp" key-value pair.
|
||||
* @returns {*} JSON Object with multiple sorted by "timestamp"
|
||||
*/
|
||||
function sortData(payload) {
|
||||
var dataFromDAS = JSON.parse(payload);
|
||||
sortedData = dataFromDAS.sort(function (a, b) {
|
||||
return a.timestamp - b.timestamp;
|
||||
});
|
||||
return sortedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the values corresponding to the keys in the "columns" (either provided in the gadget-conf or fetched via the
|
||||
* "getColumns(table)" method) array from the data object passed in.
|
||||
* @param data a JSON Object containing multiple data values fetched from the datasource with column-name:value pairs.
|
||||
* @returns {Array} an array with objects that contain the columns from the fetched "columns" and their corresponding
|
||||
* values.
|
||||
*/
|
||||
function makeRows(data) {
|
||||
var rows = [];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var record = data[i];
|
||||
var keys = Object.getOwnPropertyNames(record.values);
|
||||
keys.push();
|
||||
|
||||
var row = columns.map(function (column, i) {
|
||||
var colName = column.name;
|
||||
var recordVal = record.values[colName];
|
||||
|
||||
if (typeof recordVal == 'undefined') {
|
||||
if (column.name.toUpperCase() === "TIMESTAMP" && (record.timestamp || record.TIMESTAMP)) {
|
||||
recordVal = record.timestamp;
|
||||
} else {
|
||||
recordVal = record.values[META_TAG + colName];
|
||||
}
|
||||
}
|
||||
return recordVal;
|
||||
});
|
||||
rows.push(row);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
function makeDataTable(data) {
|
||||
var dataTable = new igviz.DataTable();
|
||||
if (columns.length > 0) {
|
||||
columns.forEach(function (column, i) {
|
||||
var type = "N";
|
||||
if (column.type == "STRING" || column.type == "string") {
|
||||
type = "C";
|
||||
} else if (column.type == "TIME" || column.type == "time") {
|
||||
type = "T";
|
||||
}
|
||||
dataTable.addColumn(column.name, type);
|
||||
});
|
||||
}
|
||||
data.forEach(function (row, index) {
|
||||
for (var i = 0; i < row.length; i++) {
|
||||
if (dataTable.metadata.types[i] == "N") {
|
||||
data[index][i] = parseInt(data[index][i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
dataTable.addRows(data);
|
||||
return dataTable;
|
||||
}
|
||||
|
||||
function drawChart(data) {
|
||||
var dataTable = makeDataTable(data);
|
||||
gadgetConfig.chartConfig.width = $("#placeholder").width();
|
||||
gadgetConfig.chartConfig.height = $("#placeholder").height() - 65;
|
||||
var chartType = gadgetConfig.chartConfig.chartType;
|
||||
var xAxis = gadgetConfig.chartConfig.xAxis;
|
||||
jQuery("#noChart").html("");
|
||||
if (chartType === "bar" && dataTable.metadata.types[xAxis] === "N") {
|
||||
dataTable.metadata.types[xAxis] = "C";
|
||||
}
|
||||
|
||||
if (gadgetConfig.chartConfig.chartType === "table" || gadgetConfig.chartConfig.chartType === "singleNumber") {
|
||||
gadgetConfig.chartConfig.height = $("#placeholder").height();
|
||||
chart = igviz.draw("#placeholder", gadgetConfig.chartConfig, dataTable);
|
||||
chart.plot(dataTable.data);
|
||||
|
||||
} else {
|
||||
chart = igviz.setUp("#placeholder", gadgetConfig.chartConfig, dataTable);
|
||||
chart.setXAxis({
|
||||
"labelAngle": -35,
|
||||
"labelAlign": "right",
|
||||
"labelDy": 0,
|
||||
"labelDx": 0,
|
||||
"titleDy": 25
|
||||
})
|
||||
.setYAxis({
|
||||
"titleDy": -30
|
||||
});
|
||||
chart.plot(dataTable.data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//stuff required for realtime charting
|
||||
function onRealTimeEventSuccessRecieval(streamId, data) {
|
||||
drawRealtimeChart(data);
|
||||
}
|
||||
|
||||
function onRealTimeEventErrorRecieval(dataError) {
|
||||
console.log("Error occurred " + dataError);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the real-time chart based on the values in the data object passed in.
|
||||
* @param data an object containing all the column:value pair data
|
||||
*/
|
||||
function drawRealtimeChart(data) {
|
||||
if (chart == null) {
|
||||
jQuery("#noChart").html("");
|
||||
gadgetConfig.chartConfig.width = $("#placeholder").width() - 110;
|
||||
gadgetConfig.chartConfig.height = $("#placeholder").height() - 40;
|
||||
|
||||
if (gadgetConfig.chartConfig.charts[0].type == "map") {
|
||||
var mapType = gadgetConfig.chartConfig.charts[0].mapType;
|
||||
|
||||
if (mapType == "world") {
|
||||
gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/';
|
||||
gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/world/';
|
||||
} else if (mapType == "usa") {
|
||||
gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usaInfo/';
|
||||
gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usa/';
|
||||
} else if (mapType == "europe") {
|
||||
gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/';
|
||||
gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/europe/';
|
||||
}
|
||||
}
|
||||
|
||||
chart = new vizg(createDataTable(convertData(data)), gadgetConfig.chartConfig);
|
||||
chart.draw("#placeholder");
|
||||
} else {
|
||||
chart.insert(convertData(data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the batch-chart based on the values in the data object passed in.
|
||||
* @param data an object containing all the column:value pair data
|
||||
*/
|
||||
function drawBatchChart(data) {
|
||||
if (chart == null) {
|
||||
jQuery("#noChart").html("");
|
||||
gadgetConfig.chartConfig.width = $("#placeholder").width() - 110;
|
||||
gadgetConfig.chartConfig.height = $("#placeholder").height() - 40;
|
||||
|
||||
if (gadgetConfig.chartConfig.charts[0].type == "map") {
|
||||
var mapType = gadgetConfig.chartConfig.charts[0].mapType;
|
||||
|
||||
if (mapType == "world") {
|
||||
gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/';
|
||||
gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/world/';
|
||||
} else if (mapType == "usa") {
|
||||
gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usaInfo/';
|
||||
gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usa/';
|
||||
} else if (mapType == "europe") {
|
||||
gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/';
|
||||
gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/europe/';
|
||||
}
|
||||
}
|
||||
|
||||
initialConfig = JSON.parse(JSON.stringify(gadgetConfig.chartConfig));
|
||||
|
||||
} else {
|
||||
gadgetConfig.chartConfig = initialConfig;
|
||||
initialConfig = JSON.parse(JSON.stringify(gadgetConfig.chartConfig));
|
||||
}
|
||||
|
||||
chart = new vizg(createDataTable(convertData(data)), gadgetConfig.chartConfig);
|
||||
chart.draw("#placeholder");
|
||||
}
|
||||
|
||||
|
||||
function convertData(data) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
for (var x = 0; x < data[i].length; x++) {
|
||||
var type = gadgetConfig.columns[x]["type"].toUpperCase();
|
||||
if (type != "STRING" && type != "BOOLEAN") {
|
||||
data[i][x] = parseFloat(data[i][x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function createDataTable(data) {
|
||||
var names = [];
|
||||
var types = [];
|
||||
|
||||
for (var i = 0; i < gadgetConfig.columns.length; i++) {
|
||||
var name = gadgetConfig.columns[i]["name"];
|
||||
names.push(name);
|
||||
var type = columns[i]["type"].toUpperCase();
|
||||
|
||||
if (type === "INT" || type === "INTEGER" || type === "FLOAT" || type === "DOUBLE") {
|
||||
type = "linear";
|
||||
} else if (gadgetConfig.columns[i]["type"].toUpperCase() == "TIME" || name.toUpperCase() == "TIME") {
|
||||
type = "time";
|
||||
} else {
|
||||
type = "ordinal";
|
||||
}
|
||||
types.push(type);
|
||||
}
|
||||
|
||||
datatable = [
|
||||
{
|
||||
"metadata": {
|
||||
"names": names,
|
||||
"types": types
|
||||
},
|
||||
"data": data
|
||||
}
|
||||
];
|
||||
return datatable;
|
||||
}
|
@ -0,0 +1,285 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
var CONSTANTS = {
|
||||
webAppName: 'outputui',
|
||||
urlSeperator: '/',
|
||||
urlGetParameter : '?lastUpdatedTime=',
|
||||
urlQueryStringBegin : '?',
|
||||
tenantUrlAttribute: 't',
|
||||
urlUnsecureTransportHttp : 'http://',
|
||||
urlUnsecureTransportWebsocket : 'ws://',
|
||||
urlSecureTransportWebsocket : 'wss://',
|
||||
urlSecureTransportHttp : 'https://',
|
||||
colon : ':',
|
||||
defaultIntervalTime : 10 * 1000,
|
||||
defaultUserDomain : 'carbon.super',
|
||||
defaultHostName : 'localhost',
|
||||
defaultNonsecurePortNumber : '9763',
|
||||
defaultSecurePortNumber : '9443',
|
||||
defaultMode : 'AUTO',
|
||||
processModeHTTP : 'HTTP',
|
||||
processModeWebSocket : 'WEBSOCKET',
|
||||
processModeAuto : 'AUTO',
|
||||
domain : 'carbon.super',
|
||||
numThousand : 1000,
|
||||
websocketTimeAppender : 400,
|
||||
secureMode : 'SECURED'
|
||||
};
|
||||
|
||||
|
||||
var websocket = null;
|
||||
var webSocketUrl;
|
||||
var httpUrl;
|
||||
var cepHostName;
|
||||
var cepPortNumber;
|
||||
var isErrorOccured = false;
|
||||
var lastUpdatedtime = -1;
|
||||
var polingInterval;
|
||||
var stream;
|
||||
var streamVersion;
|
||||
var firstPollingAttempt;
|
||||
var processMode;
|
||||
var onSuccessFunction;
|
||||
var onErrorFunction;
|
||||
var userDomainUrl = "";
|
||||
var terminateWebsocketInstance = false;
|
||||
var pollingContinue = true;
|
||||
var transportToBeUsedHttp;
|
||||
var transportToBeUsedWebsocket;
|
||||
|
||||
function subscribe(streamName,version,intervalTime,domain,
|
||||
listeningFuncSuccessData,listeningFuncErrorData,
|
||||
cepHost,cepPort,mode,secureMode, queryParams){
|
||||
|
||||
stopPollingProcesses();
|
||||
stream = streamName;
|
||||
streamVersion = version;
|
||||
onSuccessFunction = listeningFuncSuccessData;
|
||||
onErrorFunction = listeningFuncErrorData;
|
||||
|
||||
if(secureMode == CONSTANTS.secureMode){
|
||||
transportToBeUsedHttp = CONSTANTS.urlSecureTransportHttp;
|
||||
transportToBeUsedWebsocket = CONSTANTS.urlSecureTransportWebsocket;
|
||||
} else {
|
||||
transportToBeUsedHttp = CONSTANTS.urlUnsecureTransportHttp;
|
||||
transportToBeUsedWebsocket = CONSTANTS.urlUnsecureTransportWebsocket;
|
||||
}
|
||||
|
||||
if(intervalTime == null || intervalTime == ""){
|
||||
polingInterval = CONSTANTS.defaultIntervalTime;
|
||||
} else{
|
||||
polingInterval = intervalTime * CONSTANTS.numThousand;
|
||||
}
|
||||
|
||||
if(domain == null || domain == ""){
|
||||
domain = CONSTANTS.defaultUserDomain;
|
||||
}
|
||||
|
||||
if(cepHost == null || cepHost == ""){
|
||||
cepHostName = CONSTANTS.defaultHostName;
|
||||
} else{
|
||||
cepHostName = cepHost;
|
||||
}
|
||||
|
||||
if(cepPort == null || cepPort == ""){
|
||||
if(secureMode == CONSTANTS.secureMode){
|
||||
cepPortNumber = CONSTANTS.defaultSecurePortNumber;
|
||||
} else{
|
||||
cepPortNumber = CONSTANTS.defaultNonsecurePortNumber;
|
||||
}
|
||||
} else{
|
||||
cepPortNumber = cepPort;
|
||||
}
|
||||
|
||||
if(mode == null || mode == ""){
|
||||
processMode = CONSTANTS.defaultMode;
|
||||
} else{
|
||||
processMode = mode;
|
||||
}
|
||||
|
||||
if(domain != CONSTANTS.domain){
|
||||
userDomainUrl = CONSTANTS.tenantUrlAttribute + CONSTANTS.urlSeperator + domain + CONSTANTS.urlSeperator;
|
||||
|
||||
}
|
||||
|
||||
if (queryParams == null) {
|
||||
queryParams = "";
|
||||
} else if (queryParams != "") {
|
||||
queryParams = CONSTANTS.urlQueryStringBegin + queryParams;
|
||||
}
|
||||
|
||||
webSocketUrl = transportToBeUsedWebsocket + cepHostName + CONSTANTS.colon + cepPortNumber +
|
||||
CONSTANTS.urlSeperator + CONSTANTS.webAppName+ CONSTANTS.urlSeperator + userDomainUrl + stream +
|
||||
CONSTANTS.urlSeperator + streamVersion + queryParams;
|
||||
|
||||
|
||||
if(processMode == CONSTANTS.processModeHTTP){
|
||||
firstPollingAttempt = true;
|
||||
pollingContinue = true;
|
||||
startPoll();
|
||||
} else{
|
||||
initializeWebSocket(webSocketUrl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializing Web Socket
|
||||
*/
|
||||
function initializeWebSocket(webSocketUrl){
|
||||
websocket = new WebSocket(webSocketUrl);
|
||||
websocket.onopen = webSocketOnOpen;
|
||||
websocket.onmessage = webSocketOnMessage;
|
||||
websocket.onclose = webSocketOnClose;
|
||||
websocket.onerror = webSocketOnError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Web socket On Open
|
||||
*/
|
||||
|
||||
var webSocketOnOpen = function () {
|
||||
// alert("Successfully connected to "+webSocketUrl);
|
||||
//onErrorFunction("Successfully connected to URL:" + webSocketUrl + "\n");
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* On server sends a message
|
||||
*/
|
||||
var webSocketOnMessage = function (evt) {
|
||||
var event = evt.data;
|
||||
var array = JSON.parse(event);
|
||||
constructPayload(array);
|
||||
};
|
||||
|
||||
/**
|
||||
* On server close
|
||||
*/
|
||||
var webSocketOnClose =function (e) {
|
||||
|
||||
if(isErrorOccured){
|
||||
if(processMode != CONSTANTS.processModeWebSocket){
|
||||
firstPollingAttempt = true;
|
||||
pollingContinue = true;
|
||||
startPoll();
|
||||
}
|
||||
} else{
|
||||
if(!terminateWebsocketInstance){
|
||||
waitForSocketConnection(websocket);
|
||||
} else{
|
||||
terminateWebsocketInstance = false;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* On server Error
|
||||
*/
|
||||
var webSocketOnError = function (err) {
|
||||
var error = "Error: Cannot connect to Websocket URL:" + webSocketUrl + " .Hence closing the connection!";
|
||||
|
||||
onErrorFunction(error);
|
||||
isErrorOccured = true;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Gracefully increments the connection retry
|
||||
*/
|
||||
var waitTime = CONSTANTS.numThousand;
|
||||
function waitForSocketConnection(socket, callback){
|
||||
setTimeout(
|
||||
function () {
|
||||
if (socket.readyState === 1) {
|
||||
initializeWebSocket(webSocketUrl);
|
||||
console.log("Connection is made");
|
||||
if(callback != null){
|
||||
callback();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
websocket = new WebSocket(webSocketUrl);
|
||||
waitTime += CONSTANTS.websocketTimeAppender;
|
||||
waitForSocketConnection(websocket, callback);
|
||||
}
|
||||
}, waitTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Polling to retrieve events from http request periodically
|
||||
*/
|
||||
function startPoll(){
|
||||
|
||||
(function poll(){
|
||||
setTimeout(function(){
|
||||
httpUrl = transportToBeUsedHttp + cepHostName + CONSTANTS.colon + cepPortNumber + CONSTANTS.urlSeperator
|
||||
+ CONSTANTS.webAppName + CONSTANTS.urlSeperator + userDomainUrl + stream + CONSTANTS.urlSeperator +
|
||||
streamVersion + CONSTANTS.urlGetParameter + lastUpdatedtime;
|
||||
|
||||
$.getJSON(httpUrl, function(responseText) {
|
||||
if(firstPollingAttempt){
|
||||
/*var data = $("textarea#idConsole").val();
|
||||
$("textarea#idConsole").val(data + "Successfully connected to HTTP.");*/
|
||||
firstPollingAttempt = false;
|
||||
}
|
||||
|
||||
var eventList = $.parseJSON(responseText.events);
|
||||
if(eventList.length != 0){
|
||||
lastUpdatedtime = responseText.lastEventTime;
|
||||
for(var i=0;i<eventList.length;i++){
|
||||
var arr = eventList[i];
|
||||
constructPayload(arr);
|
||||
}
|
||||
}
|
||||
if(pollingContinue){
|
||||
startPoll();
|
||||
}
|
||||
})
|
||||
.fail(function(errorData) {
|
||||
var errorData = JSON.parse(errorData.responseText);
|
||||
onErrorFunction(errorData.error);
|
||||
});
|
||||
}, polingInterval);
|
||||
})()
|
||||
}
|
||||
|
||||
function stopPollingProcesses(){
|
||||
|
||||
//stopping the Websocket
|
||||
if(websocket != null){
|
||||
terminateWebsocketInstance = true;
|
||||
websocket.onclose;
|
||||
}
|
||||
//stopping the HTTPS Request
|
||||
pollingContinue = false;
|
||||
|
||||
}
|
||||
|
||||
function constructPayload(eventsArray){
|
||||
var streamId = stream + CONSTANTS.colon + streamVersion;
|
||||
var twoDimentionalArray = [eventsArray];
|
||||
onSuccessFunction(streamId,twoDimentionalArray);
|
||||
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,286 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
var CONSTANTS = {
|
||||
webAppName: 'outputui',
|
||||
urlSeperator: '/',
|
||||
urlGetParameter : '?lastUpdatedTime=',
|
||||
urlQueryStringBegin : '?',
|
||||
tenantUrlAttribute: 't',
|
||||
urlUnsecureTransportHttp : 'http://',
|
||||
urlUnsecureTransportWebsocket : 'ws://',
|
||||
urlSecureTransportWebsocket : 'wss://',
|
||||
urlSecureTransportHttp : 'https://',
|
||||
colon : ':',
|
||||
defaultIntervalTime : 10 * 1000,
|
||||
defaultUserDomain : 'carbon.super',
|
||||
defaultHostName : 'localhost',
|
||||
defaultNonsecurePortNumber : '9763',
|
||||
defaultSecurePortNumber : '9443',
|
||||
defaultMode : 'AUTO',
|
||||
processModeHTTP : 'HTTP',
|
||||
processModeWebSocket : 'WEBSOCKET',
|
||||
processModeAuto : 'AUTO',
|
||||
domain : 'carbon.super',
|
||||
numThousand : 1000,
|
||||
websocketTimeAppender : 400,
|
||||
secureMode : 'SECURED'
|
||||
};
|
||||
|
||||
|
||||
var websocket = null;
|
||||
var webSocketUrl;
|
||||
var httpUrl;
|
||||
var cepHostName;
|
||||
var cepPortNumber;
|
||||
var isErrorOccured = false;
|
||||
var lastUpdatedtime = -1;
|
||||
var polingInterval;
|
||||
var stream;
|
||||
var streamVersion;
|
||||
var firstPollingAttempt;
|
||||
var processMode;
|
||||
var onSuccessFunction;
|
||||
var onErrorFunction;
|
||||
var userDomainUrl = "";
|
||||
var terminateWebsocketInstance = false;
|
||||
var pollingContinue = true;
|
||||
var transportToBeUsedHttp;
|
||||
var transportToBeUsedWebsocket;
|
||||
|
||||
function subscribe(streamName,version,intervalTime,domain,
|
||||
listeningFuncSuccessData,listeningFuncErrorData,
|
||||
cepHost,cepPort,mode,secureMode, queryParams){
|
||||
|
||||
stopPollingProcesses();
|
||||
stream = streamName;
|
||||
streamVersion = version;
|
||||
onSuccessFunction = listeningFuncSuccessData;
|
||||
onErrorFunction = listeningFuncErrorData;
|
||||
|
||||
if(secureMode == CONSTANTS.secureMode){
|
||||
transportToBeUsedHttp = CONSTANTS.urlSecureTransportHttp;
|
||||
transportToBeUsedWebsocket = CONSTANTS.urlSecureTransportWebsocket;
|
||||
} else {
|
||||
transportToBeUsedHttp = CONSTANTS.urlUnsecureTransportHttp;
|
||||
transportToBeUsedWebsocket = CONSTANTS.urlUnsecureTransportWebsocket;
|
||||
}
|
||||
|
||||
if(intervalTime == null || intervalTime == ""){
|
||||
polingInterval = CONSTANTS.defaultIntervalTime;
|
||||
} else{
|
||||
polingInterval = intervalTime * CONSTANTS.numThousand;
|
||||
}
|
||||
|
||||
if(domain == null || domain == ""){
|
||||
domain = CONSTANTS.defaultUserDomain;
|
||||
}
|
||||
|
||||
if(cepHost == null || cepHost == ""){
|
||||
cepHostName = CONSTANTS.defaultHostName;
|
||||
} else{
|
||||
cepHostName = cepHost;
|
||||
}
|
||||
|
||||
if(cepPort == null || cepPort == ""){
|
||||
if(secureMode == CONSTANTS.secureMode){
|
||||
cepPortNumber = CONSTANTS.defaultSecurePortNumber;
|
||||
} else{
|
||||
cepPortNumber = CONSTANTS.defaultNonsecurePortNumber;
|
||||
}
|
||||
} else{
|
||||
cepPortNumber = cepPort;
|
||||
}
|
||||
|
||||
if(mode == null || mode == ""){
|
||||
processMode = CONSTANTS.defaultMode;
|
||||
} else{
|
||||
processMode = mode;
|
||||
}
|
||||
|
||||
if(domain != CONSTANTS.domain){
|
||||
userDomainUrl = CONSTANTS.tenantUrlAttribute + CONSTANTS.urlSeperator + domain + CONSTANTS.urlSeperator;
|
||||
|
||||
}
|
||||
|
||||
if (queryParams == null) {
|
||||
queryParams = "";
|
||||
} else if (queryParams != "") {
|
||||
queryParams = CONSTANTS.urlQueryStringBegin + queryParams;
|
||||
}
|
||||
|
||||
webSocketUrl = transportToBeUsedWebsocket + cepHostName + CONSTANTS.colon + cepPortNumber +
|
||||
CONSTANTS.urlSeperator + CONSTANTS.webAppName+ CONSTANTS.urlSeperator + userDomainUrl + stream +
|
||||
CONSTANTS.urlSeperator + streamVersion + queryParams;
|
||||
|
||||
|
||||
if(processMode == CONSTANTS.processModeHTTP){
|
||||
firstPollingAttempt = true;
|
||||
pollingContinue = true;
|
||||
startPoll();
|
||||
} else{
|
||||
initializeWebSocket(webSocketUrl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializing Web Socket
|
||||
*/
|
||||
function initializeWebSocket(webSocketUrl){
|
||||
websocket = new WebSocket(webSocketUrl);
|
||||
websocket.onopen = webSocketOnOpen;
|
||||
websocket.onmessage = webSocketOnMessage;
|
||||
websocket.onclose = webSocketOnClose;
|
||||
websocket.onerror = webSocketOnError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Web socket On Open
|
||||
*/
|
||||
|
||||
var webSocketOnOpen = function () {
|
||||
// alert("Successfully connected to "+webSocketUrl);
|
||||
//onErrorFunction("Successfully connected to URL:" + webSocketUrl + "\n");
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* On server sends a message
|
||||
*/
|
||||
var webSocketOnMessage = function (evt) {
|
||||
var event = evt.data;
|
||||
var array = JSON.parse(event);
|
||||
constructPayload(array);
|
||||
};
|
||||
|
||||
/**
|
||||
* On server close
|
||||
*/
|
||||
var webSocketOnClose =function (e) {
|
||||
|
||||
if(isErrorOccured){
|
||||
if(processMode != CONSTANTS.processModeWebSocket){
|
||||
firstPollingAttempt = true;
|
||||
pollingContinue = true;
|
||||
startPoll();
|
||||
}
|
||||
} else{
|
||||
if(!terminateWebsocketInstance){
|
||||
waitForSocketConnection(websocket);
|
||||
} else{
|
||||
terminateWebsocketInstance = false;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* On server Error
|
||||
*/
|
||||
var webSocketOnError = function (err) {
|
||||
var error = "Error: Cannot connect to Websocket URL:" + webSocketUrl + " .Hence closing the connection!";
|
||||
|
||||
onErrorFunction(error);
|
||||
isErrorOccured = true;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Gracefully increments the connection retry
|
||||
*/
|
||||
var waitTime = CONSTANTS.numThousand;
|
||||
function waitForSocketConnection(socket, callback){
|
||||
setTimeout(
|
||||
function () {
|
||||
if (socket.readyState === 1) {
|
||||
initializeWebSocket(webSocketUrl);
|
||||
console.log("Connection is made");
|
||||
if(callback != null){
|
||||
callback();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
websocket = new WebSocket(webSocketUrl);
|
||||
waitTime += CONSTANTS.websocketTimeAppender;
|
||||
waitForSocketConnection(websocket, callback);
|
||||
}
|
||||
}, waitTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Polling to retrieve events from http request periodically
|
||||
*/
|
||||
function startPoll(){
|
||||
|
||||
(function poll(){
|
||||
setTimeout(function(){
|
||||
httpUrl = transportToBeUsedHttp + cepHostName + CONSTANTS.colon + cepPortNumber + CONSTANTS.urlSeperator
|
||||
+ CONSTANTS.webAppName + CONSTANTS.urlSeperator + userDomainUrl + stream + CONSTANTS.urlSeperator +
|
||||
streamVersion + CONSTANTS.urlGetParameter + lastUpdatedtime;
|
||||
|
||||
$.getJSON(httpUrl, function(responseText) {
|
||||
if(firstPollingAttempt){
|
||||
/*var data = $("textarea#idConsole").val();
|
||||
$("textarea#idConsole").val(data + "Successfully connected to HTTP.");*/
|
||||
firstPollingAttempt = false;
|
||||
}
|
||||
|
||||
var eventList = $.parseJSON(responseText.events);
|
||||
if(eventList.length != 0){
|
||||
lastUpdatedtime = responseText.lastEventTime;
|
||||
for(var i=0;i<eventList.length;i++){
|
||||
var arr = eventList[i];
|
||||
constructPayload(arr);
|
||||
}
|
||||
}
|
||||
if(pollingContinue){
|
||||
startPoll();
|
||||
}
|
||||
})
|
||||
.fail(function(errorData) {
|
||||
var errorData = JSON.parse(errorData.responseText);
|
||||
onErrorFunction(errorData.error);
|
||||
});
|
||||
}, polingInterval);
|
||||
})()
|
||||
}
|
||||
|
||||
function stopPollingProcesses(){
|
||||
|
||||
//stopping the Websocket
|
||||
if(websocket != null){
|
||||
terminateWebsocketInstance = true;
|
||||
websocket.onclose;
|
||||
}
|
||||
//stopping the HTTPS Request
|
||||
pollingContinue = false;
|
||||
|
||||
}
|
||||
|
||||
function constructPayload(eventsArray){
|
||||
|
||||
var streamId = stream + CONSTANTS.colon + streamVersion;
|
||||
var twoDimentionalArray = [eventsArray];
|
||||
onSuccessFunction(streamId,twoDimentionalArray);
|
||||
|
||||
}
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 46 KiB |
Loading…
Reference in new issue