From 19a08558e3e32a9e4764acf913bdb57e043b6de4 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Sat, 14 Apr 2018 10:08:55 +0200 Subject: [PATCH] Chrome uses double for height/width of elements This caused a NumberFormatExeption when trying to convert the string representation of a double to an int. Fixed by floor'ing the value. --- pdb-ui/src/main/resources/resources/js/ui.js | 1670 +++++++++--------- 1 file changed, 835 insertions(+), 835 deletions(-) diff --git a/pdb-ui/src/main/resources/resources/js/ui.js b/pdb-ui/src/main/resources/resources/js/ui.js index 460246f..69e9c75 100644 --- a/pdb-ui/src/main/resources/resources/js/ui.js +++ b/pdb-ui/src/main/resources/resources/js/ui.js @@ -1,835 +1,835 @@ -'use strict'; - -function ffHasParentWithId(el, id) { - if (el.id == id){ - return true; - } - else if (el.parentNode) { - return ffHasParentWithId(el.parentNode, id); - } - - return false; -}; - -window.onload=function(){ - -Vue.config.keyCodes.arrowUp = 38; -Vue.config.keyCodes.arrowDown = 40; - -Vue.component('search-bar-query', { - props: ['searchBar'], - autocompleteTimeout: null, - requestNumber: 1, - created: function() { - this.requestNumber= 1; - document.addEventListener("click", function(event){ - const isSearchInput = event.path - ? event.path.map((e) => e.id == "search-input-wrapper") - .reduce((accumulator, currentValue) => accumulator || currentValue) - : ffHasParentWithId(event.explicitOriginalTarget, "search-input-wrapper"); - if(!isSearchInput){ - data.searchBar.proposals = []; - } - }); - }, - data: function() { - return { - highlightedProposal: -1, - }; - }, - methods: { - onChange: function (event) { - if (event.key == 'ArrowDown' || event.key == 'ArrowUp' || event.key == 'Enter' || event.key == 'Escape'){ - return; - } - - this.autocomplete(this, event); - }, - autocomplete: function(vm, event) { - - if(this.autocompleteTimeout) { - window.clearTimeout(this.autocompleteTimeout); - if (event) { - event.preventDefault(); - } - } - - vm.showProposals = false; - - var expectedRequestNumber = ++vm.requestNumber; - vm.autocompleteTimeout = window.setTimeout(function() { - var caretIndex = document.getElementById('search-input').selectionStart + 1; - var request='autocomplete?caretIndex=' + caretIndex + '&query='+encodeURIComponent(data.searchBar.query); - - var successCallback = function(result) { - if (expectedRequestNumber == vm.requestNumber) { - vm.highlightedProposal = -1; - vm.showProposals = true; - - var index = 0; - var proposals = result.proposals; - proposals.forEach(function(p) { - p.id = "proposal_"+index - p.index = index++; - p.highlighted=false; - }); - data.searchBar.proposals = proposals; - } else { - console.log("ignoring stale response "+ expectedRequestNumber +" != "+ vm.requestNumber); - } - }; - - var errorCallback = function(e) { - console.log("FAILED: " + JSON.parse(e.responseText).message); - vm.proposals=[]; - }; - - getJson(request, {}, successCallback, errorCallback); - }, - 300); - }, - selectOrSubmit: function(event) { - const vm = this; - if (this.highlightedProposal >= 0){ - event.preventDefault(); - var proposal = data.searchBar.proposals[this.highlightedProposal]; - data.searchBar.query = proposal.newQuery; - data.searchBar.proposals = []; - - Vue.nextTick(function () { - var el = document.getElementById('search-input'); - el.select(); - el.selectionStart=proposal.newCaretPosition; - el.selectionEnd=proposal.newCaretPosition; - - vm.autocomplete(vm); - }); - } - }, - selectUpDown: function(event) { - if (event.key == 'ArrowDown'){ - this.highlightedProposal = (this.highlightedProposal+1) % data.searchBar.proposals.length; - } else if (event.key == 'ArrowUp') { - this.highlightedProposal = (this.highlightedProposal-1) % data.searchBar.proposals.length; - this.highlightedProposal = this.highlightedProposal < 0 ? -1 : this.highlightedProposal; - } - }, - - noop: function(event){}, - }, - template: ` -
- -
- -
-
` -}); - -Vue.component('proposal-item', { - props: ['proposalItem', 'highlightedProposal'], - computed: { - isHighlighted: function() { - return this.highlightedProposal == this.proposalItem.index; - } - }, - methods: { - selectProposal: function(event) { - var proposal = data.searchBar.proposals[this.proposalItem.index]; - data.searchBar.query = proposal.newQuery; - data.searchBar.proposals = []; - - Vue.nextTick(function () { - var el = document.getElementById('search-input'); - el.select(); - el.selectionStart=proposal.newCaretPosition; - el.selectionEnd=proposal.newCaretPosition; - }); - }, - }, - template: ` -
{{ proposalItem.value }}
` -}); - - -Vue.component('result-view', { - props: ['searchBar', 'resultView'], - methods: { - prev_image: function() - { - var splitBy = data.searchBar.splitBy; - if (splitBy['values'].length > 0) - { - splitBy['index'] = (splitBy['index']+ splitBy['values'].length-1) % splitBy['values'].length; - plotCurrent(); - } - }, - next_image: function() - { - var splitBy = data.searchBar.splitBy; - if (splitBy['values'].length > 0) - { - splitBy['index'] = (splitBy['index']+1) % splitBy['values'].length; - plotCurrent(); - } - } - }, - computed: { - showPrevNext: function() { - return data.searchBar.splitBy.values.length > 0 && !data.resultView.loadingGameActive; - } - }, - template: ` -
-
-
-
-
{{ resultView.errorMessage }}
-
` -}); - -Vue.component('navigation-bar', { - props: [], - methods: { - - refresh: function() - { - plotCurrent(); - }, - zoomIn: function() - { - this.shiftDate(0.25); - this.zoom(0.5); - plotCurrent(); - }, - zoomOut: function() - { - this.shiftDate(-0.5); - this.zoom(2); - plotCurrent(); - }, - dateLeftShift: function() - { - this.shiftDate(-1); - plotCurrent(); - }, - dateHalfLeftShift: function() - { - this.shiftDate(-0.5); - plotCurrent(); - }, - dateHalfRightShift: function() - { - this.shiftDate(0.5); - plotCurrent(); - }, - dateRightShift: function() - { - this.shiftDate(1); - plotCurrent(); - }, - zoom: function(factor) - { - if (!$('#search-date-range').is(":invalid")) { - - var dateRange = data.searchBar.dateRange; - var tokens = dateRange.split(/ +/,2); - - if(tokens.length == 2) - { - var value = parseInt(tokens[0]); - var period = tokens[1]; - - var newValue = value*factor; - while (newValue != Math.round(newValue)){ - - switch (period) { - case "second": - case "seconds": - if (value == 1) { - // we reached the smallest range - } - else if (value % 2 == 1){ - value = value -1; - } - break; - case "minute": - case "minutes": - value = value * 60; - period = "seconds"; - break; - case "hour": - case "hours": - value = value * 60; - period = "minutes"; - break; - case "day": - case "days": - value = value * 24; - period = "hours"; - break; - case "week": - case "weeks": - value = value * 7; - period = "days"; - break; - case "month": - case "months": - value = value * 30; - period = "days"; - break; - default: - console.log("unhandled value: "+ period); - break; - } - - newValue = value*factor - } - - - data.searchBar.dateRange = newValue + " " + period; - } - } - }, - shiftDate: function(directionalFactor) - { - var dateBefore = Date.parse(data.searchBar.dateFrom); - var newDate = this.shiftByInterval(dateBefore, directionalFactor); - data.searchBar.dateFrom = newDate.toString("yyyy-MM-dd HH:mm:ss"); - }, - shiftByInterval: function(date, directionalFactor) - { - if (!$('#search-date-range').is(":invalid")) { - - var dateRange = data.searchBar.dateRange; - var tokens = dateRange.split(/ +/,2); - - if(tokens.length == 2) - { - var value = parseInt(tokens[0]); - var period = tokens[1]; - var config = {}; - - value = directionalFactor * value; - - switch (period) { - case "second": - case "seconds": - config = { seconds: value }; - break; - case "minute": - case "minutes": - config = { minutes: value }; - break; - case "hour": - case "hours": - config = { minutes: 60*value }; - break; - case "day": - case "days": - config = { days: value }; - break; - case "week": - case "weeks": - config = { days: 7*value }; - break; - case "month": - case "months": - config = { days: 30*value }; - break; - - default: - break; - } - - var newDate = date.add(config); - return newDate; - } - } - return date; - } - }, - template: ` - ` -}); - -Vue.component('group-by-item', { - props: ['groupBy'], - template: ` - ` -}); - -Vue.component('search-bar', { - props: ['searchBar'], - methods: { - plot: function (event) { - var vm = this; - if (this.searchBar.splitByKeys.selected){ - this.splitQueries(function (fieldValues) { - data.searchBar.splitBy['values'] = fieldValues; - vm.enableSplitBy(fieldValues); - plotCurrent(); - }); - - }else{ - this.disableSplitBy(); - plotCurrent(); - } - }, - dashboard: function (event) { - alert('dashboard'); - }, - enableSplitBy: function(fieldValues) { - data.searchBar.splitBy['field'] = data.searchBar.splitByKeys.selected; - data.searchBar.splitBy['values'] = fieldValues; - data.searchBar.splitBy['index'] = 0; - data.searchBar.splitBy['query'] = data.searchBar.query; - }, - disableSplitBy: function() { - data.searchBar.splitBy['field'] = ''; - data.searchBar.splitBy['values'] = []; - data.searchBar.splitBy['index'] = 0; - data.searchBar.splitBy['query'] = ''; - }, - splitQueries: function(successCallback) - { - var request = {}; - request['query'] = data.searchBar.query; - - var error = function(e) { - data.resultView.errorMessage = "FAILED: " + JSON.parse(e.responseText).message; - }; - - var url = "/fields/"+encodeURIComponent(data.searchBar.splitByKeys.selected)+"/values"; - getJson(url, request, successCallback, error); - }, - }, - computed: { - permalink: function() { - var groupBy = []; - data.searchBar.groupByKeys.forEach(function(e){ if (e.selected) {groupBy.push(e.selected);}}); - - var params = { - 'query': data.searchBar.query, - 'groupBy': groupBy, - 'splitByKeys.selected': data.searchBar.splitByKeys.selected, - 'limitBy.selected': data.searchBar.limitBy.selected, - 'limitBy.number': data.searchBar.limitBy.number, - 'dateFrom': data.searchBar.dateFrom, - 'dateRange': data.searchBar.dateRange, - 'axisScale': data.searchBar.axisScale, - 'plotType': data.searchBar.plotType, - 'aggregate': data.searchBar.aggregate, - 'keyOutside': data.searchBar.keyOutside, - }; - - var link = window.location.origin+ window.location.pathname + "?" + jQuery.param( params ); - return link; - } - }, - template: ` - ` -}); - -var rootView = new Vue({ - el: '#app', - data: data, - created: function() { - var self = this; - var request = {}; - - var success = function(response){ - - var options = [{ text: '', value: '' }]; - - response.forEach( (item, index) => { options.push({text: item, value: item}); } ); - - const groupByDefaults = GetURLParameterArray('groupBy'); - - for (var i = 0; i < 3; i++){ - self.searchBar.groupByKeys.push({ - 'id': 'groupByKeys'+i, - 'selected': groupByDefaults[i] ? groupByDefaults[i] : '', - 'options': options - }); - } - self.searchBar.splitByKeys.options = options - }; - var error = function(e) { - data.resultView.errorMessage = "FAILED: " + JSON.parse(e.responseText).message; - }; - - getJson("fields", request, success, error); - } -}); - -initInvaders('result-image'); - -} // end window.on-load - -var data = { - - searchBar: { - query: GetURLParameter('query', 'pod=vapfinra01 and method = ViewService.findFieldViewGroup'), - proposals: [], - groupByKeys: [], - splitByKeys: { - 'selected': GetURLParameter('splitByKeys.selected','method'), - 'options': [] - }, - limitBy: { - 'selected': GetURLParameter('limitBy.selected','NO_LIMIT'), - 'number': GetURLParameter('limitBy.number',10) - }, - dateFrom: GetURLParameter('dateFrom', Date.now().add({ days: -7 }).toString("yyyy-MM-dd HH:mm:ss")), // '2018-01-05 09:03:00' - dateRange: GetURLParameter('dateRange','1 week'), - axisScale: GetURLParameter('axisScale','LOG10'), - plotType: GetURLParameter('plotType','SCATTER'), - aggregate: GetURLParameter('aggregate','NONE'), - keyOutside: GetURLParameterBoolean('keyOutside', 'false'), - - splitBy: { - field: '', - query: '', - values: [], - index: 0 - }, - imagelink: "" - }, - resultView: { - imageUrl: '', - errorMessage: '', - loadingGameActive: false - }, -}; - - -function showLoadingIcon() -{ - data.resultView.imageUrl = ''; - data.resultView.errorMessage = ''; - data.resultView.loadingGameActive = true; - - startInvaders(); -} - -function hideLoadingIcon() -{ - data.resultView.loadingGameActive = false; - pauseInvaders(); -} - -function plotCurrent() -{ - showLoadingIcon(); - - if (data.searchBar.splitBy['field']) { - var query = createQuery(); - sendPlotRequest(query); - }else{ - sendPlotRequest(data.searchBar.query); - } -} - -function createQuery() -{ - var splitBy = data.searchBar.splitBy; - var query = splitBy['query']; - if (query.length > 0) { - query = "("+query+") and "+splitBy['field']+ " = " +splitBy['values'][splitBy['index']]; - } else { - query = splitBy['field']+ " = " +splitBy['values'][splitBy['index']]; - } - return query; -} - - -function groupBy() -{ - var result = []; - data.searchBar.groupByKeys.forEach(function(item) { - if (item.selected) { - result.push(item.selected); - } - }); - return result; -} - -function sendPlotRequest(query){ - - var request = {}; - request['query'] = query; - request['height'] = $('#result-image').height(); - request['width'] = $('#result-image').width(); - request['groupBy'] = groupBy(); - request['limitBy'] = data.searchBar.limitBy.selected; - request['limit'] = parseInt(data.searchBar.limitBy.number); - request['dateFrom'] = data.searchBar.dateFrom; - request['dateRange'] = data.searchBar.dateRange; - request['axisScale'] = data.searchBar.axisScale; - request['plotType'] = data.searchBar.plotType; - request['aggregate'] = data.searchBar.aggregate; - request['keyOutside'] = data.searchBar.keyOutside; - - - var success = function(response){ - data.resultView.imageUrl = response.imageUrl; - data.resultView.errorMessage = ''; - hideLoadingIcon(); - updateImageLink(query); - }; - var error = function(e) { - data.resultView.imageUrl = ''; - if (e.status == 404){ - data.resultView.errorMessage = "No data points found for query: " + query; - } - else if (e.status == 503){ - data.resultView.errorMessage = "Too many parallel requests."; - } - else{ - data.resultView.errorMessage = "FAILED: " + JSON.parse(e.responseText).message; - } - hideLoadingIcon(); - }; - - data.searchBar.imagelink = ''; - postJson("plots", request, success, error); -} - -function updateImageLink(query) { - - var groupBy = []; - data.searchBar.groupByKeys.forEach(function(e){ if (e.selected) {groupBy.push(e.selected);}}); - - var params = { - 'query': query, - 'groupBy': groupBy, - 'splitByKeys.selected': data.searchBar.splitByKeys.selected, - 'limitBy.selected': data.searchBar.limitBy.selected, - 'limitBy.number': data.searchBar.limitBy.number, - 'dateFrom': data.searchBar.dateFrom, - 'dateRange': data.searchBar.dateRange, - 'axisScale': data.searchBar.axisScale, - 'plotType': data.searchBar.plotType, - 'aggregate': data.searchBar.aggregate, - 'keyOutside': data.searchBar.keyOutside, - 'width': $('#result-image').width(), - 'height': $('#result-image').height() - }; - - data.searchBar.imagelink = window.location.origin+ window.location.pathname + "plots?" + jQuery.param(params); -} - -function postJson(url, requestData, successCallback, errorCallback) { - - $.ajax({ - type: "POST", - url: url, - data: JSON.stringify(requestData), - contentType: 'application/json' - }) - .done(successCallback) - .fail(errorCallback); -} - -function getJson(url, requestData, successCallback, errorCallback) { - - $.ajax({ - type: "GET", - url: url, - data: requestData, - contentType: 'application/json' - }) - .done(successCallback) - .fail(errorCallback); -} - -function GetURLParameter(paramName, defaultValue) -{ - var pageURL = window.location.search.substring(1); - var URLVariables = pageURL.split('&'); - for (var i = 0; i < URLVariables.length; i++) - { - var keyValue = URLVariables[i].split('='); - if (keyValue[0] == paramName) - { - return decodeURIComponent(keyValue[1]); - } - } - return defaultValue; -} - -function GetURLParameterArray(paramName) -{ - var result = []; - var pageURL = window.location.search.substring(1); - var URLVariables = pageURL.split('&'); - for (var i = 0; i < URLVariables.length; i++) - { - var keyValue = URLVariables[i].split('='); - if (decodeURIComponent(keyValue[0]) == paramName+"[]") - { - result.push(decodeURIComponent(keyValue[1])); - } - } - return result; -} - -function GetURLParameterBoolean(paramName, defaultValue){ - return GetURLParameter(paramName, defaultValue) == 'true'; -} - +'use strict'; + +function ffHasParentWithId(el, id) { + if (el.id == id){ + return true; + } + else if (el.parentNode) { + return ffHasParentWithId(el.parentNode, id); + } + + return false; +}; + +window.onload=function(){ + +Vue.config.keyCodes.arrowUp = 38; +Vue.config.keyCodes.arrowDown = 40; + +Vue.component('search-bar-query', { + props: ['searchBar'], + autocompleteTimeout: null, + requestNumber: 1, + created: function() { + this.requestNumber= 1; + document.addEventListener("click", function(event){ + const isSearchInput = event.path + ? event.path.map((e) => e.id == "search-input-wrapper") + .reduce((accumulator, currentValue) => accumulator || currentValue) + : ffHasParentWithId(event.explicitOriginalTarget, "search-input-wrapper"); + if(!isSearchInput){ + data.searchBar.proposals = []; + } + }); + }, + data: function() { + return { + highlightedProposal: -1, + }; + }, + methods: { + onChange: function (event) { + if (event.key == 'ArrowDown' || event.key == 'ArrowUp' || event.key == 'Enter' || event.key == 'Escape'){ + return; + } + + this.autocomplete(this, event); + }, + autocomplete: function(vm, event) { + + if(this.autocompleteTimeout) { + window.clearTimeout(this.autocompleteTimeout); + if (event) { + event.preventDefault(); + } + } + + vm.showProposals = false; + + var expectedRequestNumber = ++vm.requestNumber; + vm.autocompleteTimeout = window.setTimeout(function() { + var caretIndex = document.getElementById('search-input').selectionStart + 1; + var request='autocomplete?caretIndex=' + caretIndex + '&query='+encodeURIComponent(data.searchBar.query); + + var successCallback = function(result) { + if (expectedRequestNumber == vm.requestNumber) { + vm.highlightedProposal = -1; + vm.showProposals = true; + + var index = 0; + var proposals = result.proposals; + proposals.forEach(function(p) { + p.id = "proposal_"+index + p.index = index++; + p.highlighted=false; + }); + data.searchBar.proposals = proposals; + } else { + console.log("ignoring stale response "+ expectedRequestNumber +" != "+ vm.requestNumber); + } + }; + + var errorCallback = function(e) { + console.log("FAILED: " + JSON.parse(e.responseText).message); + vm.proposals=[]; + }; + + getJson(request, {}, successCallback, errorCallback); + }, + 300); + }, + selectOrSubmit: function(event) { + const vm = this; + if (this.highlightedProposal >= 0){ + event.preventDefault(); + var proposal = data.searchBar.proposals[this.highlightedProposal]; + data.searchBar.query = proposal.newQuery; + data.searchBar.proposals = []; + + Vue.nextTick(function () { + var el = document.getElementById('search-input'); + el.select(); + el.selectionStart=proposal.newCaretPosition; + el.selectionEnd=proposal.newCaretPosition; + + vm.autocomplete(vm); + }); + } + }, + selectUpDown: function(event) { + if (event.key == 'ArrowDown'){ + this.highlightedProposal = (this.highlightedProposal+1) % data.searchBar.proposals.length; + } else if (event.key == 'ArrowUp') { + this.highlightedProposal = (this.highlightedProposal-1) % data.searchBar.proposals.length; + this.highlightedProposal = this.highlightedProposal < 0 ? -1 : this.highlightedProposal; + } + }, + + noop: function(event){}, + }, + template: ` +
+ +
+ +
+
` +}); + +Vue.component('proposal-item', { + props: ['proposalItem', 'highlightedProposal'], + computed: { + isHighlighted: function() { + return this.highlightedProposal == this.proposalItem.index; + } + }, + methods: { + selectProposal: function(event) { + var proposal = data.searchBar.proposals[this.proposalItem.index]; + data.searchBar.query = proposal.newQuery; + data.searchBar.proposals = []; + + Vue.nextTick(function () { + var el = document.getElementById('search-input'); + el.select(); + el.selectionStart=proposal.newCaretPosition; + el.selectionEnd=proposal.newCaretPosition; + }); + }, + }, + template: ` +
{{ proposalItem.value }}
` +}); + + +Vue.component('result-view', { + props: ['searchBar', 'resultView'], + methods: { + prev_image: function() + { + var splitBy = data.searchBar.splitBy; + if (splitBy['values'].length > 0) + { + splitBy['index'] = (splitBy['index']+ splitBy['values'].length-1) % splitBy['values'].length; + plotCurrent(); + } + }, + next_image: function() + { + var splitBy = data.searchBar.splitBy; + if (splitBy['values'].length > 0) + { + splitBy['index'] = (splitBy['index']+1) % splitBy['values'].length; + plotCurrent(); + } + } + }, + computed: { + showPrevNext: function() { + return data.searchBar.splitBy.values.length > 0 && !data.resultView.loadingGameActive; + } + }, + template: ` +
+
+
+
+
{{ resultView.errorMessage }}
+
` +}); + +Vue.component('navigation-bar', { + props: [], + methods: { + + refresh: function() + { + plotCurrent(); + }, + zoomIn: function() + { + this.shiftDate(0.25); + this.zoom(0.5); + plotCurrent(); + }, + zoomOut: function() + { + this.shiftDate(-0.5); + this.zoom(2); + plotCurrent(); + }, + dateLeftShift: function() + { + this.shiftDate(-1); + plotCurrent(); + }, + dateHalfLeftShift: function() + { + this.shiftDate(-0.5); + plotCurrent(); + }, + dateHalfRightShift: function() + { + this.shiftDate(0.5); + plotCurrent(); + }, + dateRightShift: function() + { + this.shiftDate(1); + plotCurrent(); + }, + zoom: function(factor) + { + if (!$('#search-date-range').is(":invalid")) { + + var dateRange = data.searchBar.dateRange; + var tokens = dateRange.split(/ +/,2); + + if(tokens.length == 2) + { + var value = parseInt(tokens[0]); + var period = tokens[1]; + + var newValue = value*factor; + while (newValue != Math.round(newValue)){ + + switch (period) { + case "second": + case "seconds": + if (value == 1) { + // we reached the smallest range + } + else if (value % 2 == 1){ + value = value -1; + } + break; + case "minute": + case "minutes": + value = value * 60; + period = "seconds"; + break; + case "hour": + case "hours": + value = value * 60; + period = "minutes"; + break; + case "day": + case "days": + value = value * 24; + period = "hours"; + break; + case "week": + case "weeks": + value = value * 7; + period = "days"; + break; + case "month": + case "months": + value = value * 30; + period = "days"; + break; + default: + console.log("unhandled value: "+ period); + break; + } + + newValue = value*factor + } + + + data.searchBar.dateRange = newValue + " " + period; + } + } + }, + shiftDate: function(directionalFactor) + { + var dateBefore = Date.parse(data.searchBar.dateFrom); + var newDate = this.shiftByInterval(dateBefore, directionalFactor); + data.searchBar.dateFrom = newDate.toString("yyyy-MM-dd HH:mm:ss"); + }, + shiftByInterval: function(date, directionalFactor) + { + if (!$('#search-date-range').is(":invalid")) { + + var dateRange = data.searchBar.dateRange; + var tokens = dateRange.split(/ +/,2); + + if(tokens.length == 2) + { + var value = parseInt(tokens[0]); + var period = tokens[1]; + var config = {}; + + value = directionalFactor * value; + + switch (period) { + case "second": + case "seconds": + config = { seconds: value }; + break; + case "minute": + case "minutes": + config = { minutes: value }; + break; + case "hour": + case "hours": + config = { minutes: 60*value }; + break; + case "day": + case "days": + config = { days: value }; + break; + case "week": + case "weeks": + config = { days: 7*value }; + break; + case "month": + case "months": + config = { days: 30*value }; + break; + + default: + break; + } + + var newDate = date.add(config); + return newDate; + } + } + return date; + } + }, + template: ` + ` +}); + +Vue.component('group-by-item', { + props: ['groupBy'], + template: ` + ` +}); + +Vue.component('search-bar', { + props: ['searchBar'], + methods: { + plot: function (event) { + var vm = this; + if (this.searchBar.splitByKeys.selected){ + this.splitQueries(function (fieldValues) { + data.searchBar.splitBy['values'] = fieldValues; + vm.enableSplitBy(fieldValues); + plotCurrent(); + }); + + }else{ + this.disableSplitBy(); + plotCurrent(); + } + }, + dashboard: function (event) { + alert('dashboard'); + }, + enableSplitBy: function(fieldValues) { + data.searchBar.splitBy['field'] = data.searchBar.splitByKeys.selected; + data.searchBar.splitBy['values'] = fieldValues; + data.searchBar.splitBy['index'] = 0; + data.searchBar.splitBy['query'] = data.searchBar.query; + }, + disableSplitBy: function() { + data.searchBar.splitBy['field'] = ''; + data.searchBar.splitBy['values'] = []; + data.searchBar.splitBy['index'] = 0; + data.searchBar.splitBy['query'] = ''; + }, + splitQueries: function(successCallback) + { + var request = {}; + request['query'] = data.searchBar.query; + + var error = function(e) { + data.resultView.errorMessage = "FAILED: " + JSON.parse(e.responseText).message; + }; + + var url = "/fields/"+encodeURIComponent(data.searchBar.splitByKeys.selected)+"/values"; + getJson(url, request, successCallback, error); + }, + }, + computed: { + permalink: function() { + var groupBy = []; + data.searchBar.groupByKeys.forEach(function(e){ if (e.selected) {groupBy.push(e.selected);}}); + + var params = { + 'query': data.searchBar.query, + 'groupBy': groupBy, + 'splitByKeys.selected': data.searchBar.splitByKeys.selected, + 'limitBy.selected': data.searchBar.limitBy.selected, + 'limitBy.number': data.searchBar.limitBy.number, + 'dateFrom': data.searchBar.dateFrom, + 'dateRange': data.searchBar.dateRange, + 'axisScale': data.searchBar.axisScale, + 'plotType': data.searchBar.plotType, + 'aggregate': data.searchBar.aggregate, + 'keyOutside': data.searchBar.keyOutside, + }; + + var link = window.location.origin+ window.location.pathname + "?" + jQuery.param( params ); + return link; + } + }, + template: ` + ` +}); + +var rootView = new Vue({ + el: '#app', + data: data, + created: function() { + var self = this; + var request = {}; + + var success = function(response){ + + var options = [{ text: '', value: '' }]; + + response.forEach( (item, index) => { options.push({text: item, value: item}); } ); + + const groupByDefaults = GetURLParameterArray('groupBy'); + + for (var i = 0; i < 3; i++){ + self.searchBar.groupByKeys.push({ + 'id': 'groupByKeys'+i, + 'selected': groupByDefaults[i] ? groupByDefaults[i] : '', + 'options': options + }); + } + self.searchBar.splitByKeys.options = options + }; + var error = function(e) { + data.resultView.errorMessage = "FAILED: " + JSON.parse(e.responseText).message; + }; + + getJson("fields", request, success, error); + } +}); + +initInvaders('result-image'); + +} // end window.on-load + +var data = { + + searchBar: { + query: GetURLParameter('query', 'pod=vapfinra01 and method = ViewService.findFieldViewGroup'), + proposals: [], + groupByKeys: [], + splitByKeys: { + 'selected': GetURLParameter('splitByKeys.selected','method'), + 'options': [] + }, + limitBy: { + 'selected': GetURLParameter('limitBy.selected','NO_LIMIT'), + 'number': GetURLParameter('limitBy.number',10) + }, + dateFrom: GetURLParameter('dateFrom', Date.now().add({ days: -7 }).toString("yyyy-MM-dd HH:mm:ss")), // '2018-01-05 09:03:00' + dateRange: GetURLParameter('dateRange','1 week'), + axisScale: GetURLParameter('axisScale','LOG10'), + plotType: GetURLParameter('plotType','SCATTER'), + aggregate: GetURLParameter('aggregate','NONE'), + keyOutside: GetURLParameterBoolean('keyOutside', 'false'), + + splitBy: { + field: '', + query: '', + values: [], + index: 0 + }, + imagelink: "" + }, + resultView: { + imageUrl: '', + errorMessage: '', + loadingGameActive: false + }, +}; + + +function showLoadingIcon() +{ + data.resultView.imageUrl = ''; + data.resultView.errorMessage = ''; + data.resultView.loadingGameActive = true; + + startInvaders(); +} + +function hideLoadingIcon() +{ + data.resultView.loadingGameActive = false; + pauseInvaders(); +} + +function plotCurrent() +{ + showLoadingIcon(); + + if (data.searchBar.splitBy['field']) { + var query = createQuery(); + sendPlotRequest(query); + }else{ + sendPlotRequest(data.searchBar.query); + } +} + +function createQuery() +{ + var splitBy = data.searchBar.splitBy; + var query = splitBy['query']; + if (query.length > 0) { + query = "("+query+") and "+splitBy['field']+ " = " +splitBy['values'][splitBy['index']]; + } else { + query = splitBy['field']+ " = " +splitBy['values'][splitBy['index']]; + } + return query; +} + + +function groupBy() +{ + var result = []; + data.searchBar.groupByKeys.forEach(function(item) { + if (item.selected) { + result.push(item.selected); + } + }); + return result; +} + +function sendPlotRequest(query){ + + var request = {}; + request['query'] = query; + request['height'] = Math.floor($('#result-image').height()); + request['width'] = Math.floor($('#result-image').width()); + request['groupBy'] = groupBy(); + request['limitBy'] = data.searchBar.limitBy.selected; + request['limit'] = parseInt(data.searchBar.limitBy.number); + request['dateFrom'] = data.searchBar.dateFrom; + request['dateRange'] = data.searchBar.dateRange; + request['axisScale'] = data.searchBar.axisScale; + request['plotType'] = data.searchBar.plotType; + request['aggregate'] = data.searchBar.aggregate; + request['keyOutside'] = data.searchBar.keyOutside; + + + var success = function(response){ + data.resultView.imageUrl = response.imageUrl; + data.resultView.errorMessage = ''; + hideLoadingIcon(); + updateImageLink(query); + }; + var error = function(e) { + data.resultView.imageUrl = ''; + if (e.status == 404){ + data.resultView.errorMessage = "No data points found for query: " + query; + } + else if (e.status == 503){ + data.resultView.errorMessage = "Too many parallel requests."; + } + else{ + data.resultView.errorMessage = "FAILED: " + JSON.parse(e.responseText).message; + } + hideLoadingIcon(); + }; + + data.searchBar.imagelink = ''; + postJson("plots", request, success, error); +} + +function updateImageLink(query) { + + var groupBy = []; + data.searchBar.groupByKeys.forEach(function(e){ if (e.selected) {groupBy.push(e.selected);}}); + + var params = { + 'query': query, + 'groupBy': groupBy, + 'splitByKeys.selected': data.searchBar.splitByKeys.selected, + 'limitBy.selected': data.searchBar.limitBy.selected, + 'limitBy.number': data.searchBar.limitBy.number, + 'dateFrom': data.searchBar.dateFrom, + 'dateRange': data.searchBar.dateRange, + 'axisScale': data.searchBar.axisScale, + 'plotType': data.searchBar.plotType, + 'aggregate': data.searchBar.aggregate, + 'keyOutside': data.searchBar.keyOutside, + 'width': Math.floor($('#result-image').width()), + 'height': Math.floor($('#result-image').height()) + }; + + data.searchBar.imagelink = window.location.origin+ window.location.pathname + "plots?" + jQuery.param(params); +} + +function postJson(url, requestData, successCallback, errorCallback) { + + $.ajax({ + type: "POST", + url: url, + data: JSON.stringify(requestData), + contentType: 'application/json' + }) + .done(successCallback) + .fail(errorCallback); +} + +function getJson(url, requestData, successCallback, errorCallback) { + + $.ajax({ + type: "GET", + url: url, + data: requestData, + contentType: 'application/json' + }) + .done(successCallback) + .fail(errorCallback); +} + +function GetURLParameter(paramName, defaultValue) +{ + var pageURL = window.location.search.substring(1); + var URLVariables = pageURL.split('&'); + for (var i = 0; i < URLVariables.length; i++) + { + var keyValue = URLVariables[i].split('='); + if (keyValue[0] == paramName) + { + return decodeURIComponent(keyValue[1]); + } + } + return defaultValue; +} + +function GetURLParameterArray(paramName) +{ + var result = []; + var pageURL = window.location.search.substring(1); + var URLVariables = pageURL.split('&'); + for (var i = 0; i < URLVariables.length; i++) + { + var keyValue = URLVariables[i].split('='); + if (decodeURIComponent(keyValue[0]) == paramName+"[]") + { + result.push(decodeURIComponent(keyValue[1])); + } + } + return result; +} + +function GetURLParameterBoolean(paramName, defaultValue){ + return GetURLParameter(paramName, defaultValue) == 'true'; +} +