add dashboard
This commit is contained in:
@@ -83,10 +83,13 @@ textarea {
|
||||
background: #eee;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
overflow: auto;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
#result-view {
|
||||
}
|
||||
|
||||
#filter-bar {
|
||||
grid-area: filter_bar;
|
||||
}
|
||||
@@ -139,11 +142,12 @@ textarea {
|
||||
margin-right:3px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#result-image {
|
||||
height: 100%;
|
||||
}
|
||||
#result-image img {
|
||||
display:block; /* removes 3 pixels extra height around the image */
|
||||
}
|
||||
|
||||
#prev_image, #next_image {
|
||||
position: absolute;
|
||||
@@ -175,6 +179,25 @@ textarea {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.dashboard-item {
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
margin: 10px;
|
||||
float: left;
|
||||
background: white;
|
||||
box-shadow: 5px 5px 10px 0px #aaa;
|
||||
}
|
||||
|
||||
.dashboard-item img {
|
||||
max-width: 300px;
|
||||
max-height: 180px;
|
||||
display:block; /* removes 3 pixels extra height around the image */
|
||||
}
|
||||
|
||||
.dashboard-item fieldValue{
|
||||
|
||||
}
|
||||
|
||||
.center
|
||||
{
|
||||
display: flex;
|
||||
|
||||
@@ -207,14 +207,40 @@ Vue.component('result-view', {
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div id="result">
|
||||
<div id="prev_image" v-show="showPrevNext" v-on:click="prev_image" title="Previous Plot"><i class="fa fa-angle-double-left" aria-hidden="true"></i></div>
|
||||
<div id="next_image" v-show="showPrevNext" v-on:click="next_image" title="Next Plot"><i class="fa fa-angle-double-right" aria-hidden="true"></i></div>
|
||||
<div id="result-view" v-if="resultView.imageUrl || resultView.errorMessage">
|
||||
<div id="prev_image" v-if="showPrevNext" v-on:click="prev_image" title="Previous Plot"><i class="fa fa-angle-double-left" aria-hidden="true"></i></div>
|
||||
<div id="next_image" v-if="showPrevNext" v-on:click="next_image" title="Next Plot"><i class="fa fa-angle-double-right" aria-hidden="true"></i></div>
|
||||
<div id="result-image"><img v-bind:src="resultView.imageUrl" v-if="resultView.imageUrl"/></div>
|
||||
<div id="result-error-message" v-if="resultView.errorMessage">{{ resultView.errorMessage }}</div>
|
||||
</div>`
|
||||
});
|
||||
|
||||
Vue.component('result-view-dashboard', {
|
||||
props: ['dashboard'],
|
||||
methods: {
|
||||
},
|
||||
template: `
|
||||
<div id="result-view-dashboard"
|
||||
v-if="dashboard.tiles">
|
||||
<result-view-dashboard-item
|
||||
v-for="item in dashboard.tiles"
|
||||
v-bind:key="item.fieldValue"
|
||||
v-bind:dashboardItem="item"
|
||||
></result-view-dashboard-item>
|
||||
</div>
|
||||
`
|
||||
});
|
||||
|
||||
Vue.component('result-view-dashboard-item', {
|
||||
props: ['dashboardItem'],
|
||||
template: `
|
||||
<div class="dashboard-item">
|
||||
<div class="error-message" v-if="dashboardItem.error">{{ dashboardItem.error }}</div>
|
||||
<img v-bind:src="dashboardItem.thumbnailUrl" v-if="dashboardItem.thumbnailUrl" />
|
||||
<div class="fieldValue">{{ dashboardItem.fieldValue }}</div>
|
||||
</div>`
|
||||
});
|
||||
|
||||
Vue.component('navigation-bar', {
|
||||
props: [],
|
||||
methods: {
|
||||
@@ -376,17 +402,22 @@ Vue.component('navigation-bar', {
|
||||
return date;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
navigationDisabled: function() {
|
||||
return !data.resultView.imageUrl;
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div id="navigation">
|
||||
<button id="nav_left" v-on:click="dateLeftShift" title="Show Older Values"><i class="fa fa-angle-double-left" aria-hidden="true"></i></button>
|
||||
<button id="nav_left_half" v-on:click="dateHalfLeftShift" title="Show Older Values"><i class="fa fa-angle-left" aria-hidden="true"></i></button>
|
||||
<button id="nav_left" v-on:click="dateLeftShift" :disabled="navigationDisabled" title="Show Older Values"><i class="fa fa-angle-double-left" aria-hidden="true"></i></button>
|
||||
<button id="nav_left_half" v-on:click="dateHalfLeftShift" :disabled="navigationDisabled" title="Show Older Values"><i class="fa fa-angle-left" aria-hidden="true"></i></button>
|
||||
<div>
|
||||
<button id="zoom_in" v-on:click="zoomIn" title="Zoom In"><i class="fa fa-plus-circle" aria-hidden="true"></i></button>
|
||||
<button id="refresh" v-on:click="refresh" title="Refresh"><i class="fa fa-refresh" aria-hidden="true"></i></button>
|
||||
<button id="zoom_out" v-on:click="zoomOut" title="Zoom Out"><i class="fa fa-minus-circle" aria-hidden="true"></i></button>
|
||||
<button id="zoom_in" v-on:click="zoomIn" :disabled="navigationDisabled" title="Zoom In"><i class="fa fa-plus-circle" aria-hidden="true"></i></button>
|
||||
<button id="refresh" v-on:click="refresh" :disabled="navigationDisabled" title="Refresh"><i class="fa fa-refresh" aria-hidden="true"></i></button>
|
||||
<button id="zoom_out" v-on:click="zoomOut" :disabled="navigationDisabled" title="Zoom Out"><i class="fa fa-minus-circle" aria-hidden="true"></i></button>
|
||||
</div>
|
||||
<button id="nav_right_half" v-on:click="dateHalfRightShift" title="Show Newer Values"><i class="fa fa-angle-right" aria-hidden="true"></i></button>
|
||||
<button id="nav_right" v-on:click="dateRightShift" title="Show Newer Values"><i class="fa fa-angle-double-right" aria-hidden="true"></i></button>
|
||||
<button id="nav_right_half" v-on:click="dateHalfRightShift" :disabled="navigationDisabled" title="Show Newer Values"><i class="fa fa-angle-right" aria-hidden="true"></i></button>
|
||||
<button id="nav_right" v-on:click="dateRightShift" :disabled="navigationDisabled" title="Show Newer Values"><i class="fa fa-angle-double-right" aria-hidden="true"></i></button>
|
||||
</div>`
|
||||
});
|
||||
|
||||
@@ -418,8 +449,8 @@ Vue.component('search-bar', {
|
||||
plotCurrent();
|
||||
}
|
||||
},
|
||||
dashboard: function (event) {
|
||||
alert('dashboard');
|
||||
createNewDashboard: function (event) {
|
||||
createDashboard(this);
|
||||
},
|
||||
enableSplitBy: function(fieldValues) {
|
||||
data.searchBar.splitBy['field'] = data.searchBar.splitByKeys.selected;
|
||||
@@ -467,6 +498,9 @@ Vue.component('search-bar', {
|
||||
|
||||
var link = window.location.origin+ window.location.pathname + "?" + jQuery.param( params );
|
||||
return link;
|
||||
},
|
||||
dashboardActive: function (){
|
||||
return data.searchBar.splitByKeys.selected != "";
|
||||
}
|
||||
},
|
||||
template: `
|
||||
@@ -573,13 +607,12 @@ Vue.component('search-bar', {
|
||||
title="Create Plot"
|
||||
v-on:click.prevent.stop="plot"
|
||||
><i class="fa fa-area-chart" aria-hidden="true"></i> Plot</button>
|
||||
<!--
|
||||
<button
|
||||
id="dashboard-submit"
|
||||
title="Create Dashboard"
|
||||
v-on:click.prevent.stop="dashboard"
|
||||
title="Create Dashboard (only active if 'Split' is set)"
|
||||
:disabled="!dashboardActive"
|
||||
v-on:click.prevent.stop="createNewDashboard"
|
||||
><i class="fa fa-object-group" aria-hidden="true"></i> Dashboard</button>
|
||||
-->
|
||||
<a v-bind:href="permalink" v-show="permalink" title="Permanent link to the current settings." class="permalink"><i class="fa fa-sliders" aria-hidden="true"></i></a>
|
||||
<a v-bind:href="searchBar.imagelink" v-show="searchBar.imagelink" title="Image Link" class="permalink"><i class="fa fa-image" aria-hidden="true"></i></a>
|
||||
|
||||
@@ -658,13 +691,15 @@ var data = {
|
||||
errorMessage: '',
|
||||
loadingGameActive: false
|
||||
},
|
||||
dashboard: {
|
||||
tiles: []
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function showLoadingIcon()
|
||||
{
|
||||
data.resultView.imageUrl = '';
|
||||
data.resultView.errorMessage = '';
|
||||
hidePlotAndDashboard();
|
||||
data.resultView.loadingGameActive = true;
|
||||
|
||||
startInvaders();
|
||||
@@ -676,26 +711,35 @@ function hideLoadingIcon()
|
||||
pauseInvaders();
|
||||
}
|
||||
|
||||
function hidePlotAndDashboard()
|
||||
{
|
||||
data.resultView.imageUrl = '';
|
||||
data.resultView.errorMessage = '';
|
||||
data.dashboard.tiles = [];
|
||||
}
|
||||
|
||||
function plotCurrent()
|
||||
{
|
||||
showLoadingIcon();
|
||||
|
||||
if (data.searchBar.splitBy['field']) {
|
||||
var query = createQuery();
|
||||
var splitBy = data.searchBar.splitBy;
|
||||
var originalQuery = splitBy['query'];
|
||||
var splitByField = splitBy['field'];
|
||||
var splitByValue = splitBy['values'][splitBy['index']];
|
||||
var query = createQuery(originalQuery, splitByField, splitByValue);
|
||||
sendPlotRequest(query);
|
||||
}else{
|
||||
sendPlotRequest(data.searchBar.query);
|
||||
}
|
||||
}
|
||||
|
||||
function createQuery()
|
||||
function createQuery(query, splitByField, splitByValue)
|
||||
{
|
||||
var splitBy = data.searchBar.splitBy;
|
||||
var query = splitBy['query'];
|
||||
if (query.length > 0) {
|
||||
query = "("+query+") and "+splitBy['field']+ " = " +splitBy['values'][splitBy['index']];
|
||||
query = "("+query+") and "+splitByField+ " = " +splitByValue;
|
||||
} else {
|
||||
query = splitBy['field']+ " = " +splitBy['values'][splitBy['index']];
|
||||
query = splitByField+ " = " +splitByValue;
|
||||
}
|
||||
return query;
|
||||
}
|
||||
@@ -712,12 +756,11 @@ function groupBy()
|
||||
return result;
|
||||
}
|
||||
|
||||
function sendPlotRequest(query){
|
||||
|
||||
function createRequest(query){
|
||||
var request = {};
|
||||
request['query'] = query;
|
||||
request['height'] = Math.floor($('#result-image').height());
|
||||
request['width'] = Math.floor($('#result-image').width());
|
||||
request['height'] = Math.floor($('#result').height());
|
||||
request['width'] = Math.floor($('#result').width());
|
||||
request['groupBy'] = groupBy();
|
||||
request['limitBy'] = data.searchBar.limitBy.selected;
|
||||
request['limit'] = parseInt(data.searchBar.limitBy.number);
|
||||
@@ -728,14 +771,19 @@ function sendPlotRequest(query){
|
||||
request['aggregate'] = data.searchBar.aggregate;
|
||||
request['keyOutside'] = data.searchBar.keyOutside;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
function sendPlotRequest(query){
|
||||
const request = createRequest(query);
|
||||
|
||||
var success = function(response){
|
||||
const success = function(response){
|
||||
data.resultView.imageUrl = response.imageUrl;
|
||||
data.resultView.errorMessage = '';
|
||||
hideLoadingIcon();
|
||||
updateImageLink(query);
|
||||
};
|
||||
var error = function(e) {
|
||||
const error = function(e) {
|
||||
data.resultView.imageUrl = '';
|
||||
if (e.status == 404){
|
||||
data.resultView.errorMessage = "No data points found for query: " + query;
|
||||
@@ -770,13 +818,74 @@ function updateImageLink(query) {
|
||||
'plotType': data.searchBar.plotType,
|
||||
'aggregate': data.searchBar.aggregate,
|
||||
'keyOutside': data.searchBar.keyOutside,
|
||||
'width': Math.floor($('#result-image').width()),
|
||||
'height': Math.floor($('#result-image').height())
|
||||
'width': Math.floor($('#result').width()),
|
||||
'height': Math.floor($('#result').height())
|
||||
};
|
||||
|
||||
data.searchBar.imagelink = window.location.origin+ window.location.pathname + "plots?" + jQuery.param(params);
|
||||
}
|
||||
|
||||
function createDashboard(vm){
|
||||
|
||||
hidePlotAndDashboard();
|
||||
|
||||
const imageHeight = Math.floor($('#app').height() - $('#search-bar').height() - $('#navigation').height());
|
||||
const imageWidth = Math.floor($('#app').width()- $('#search-bar').width() - $('#navigation').width());
|
||||
|
||||
const originalQuery = data.searchBar.query;
|
||||
vm.splitQueries(function (fieldValues) {
|
||||
var splitByField = data.searchBar.splitByKeys.selected;
|
||||
|
||||
createDashboardItem(fieldValues, originalQuery, splitByField, imageHeight, imageWidth);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function createDashboardItem(fieldValues, originalQuery, field, imageHeight, imageWidth)
|
||||
{
|
||||
if (fieldValues.length > 0) {
|
||||
var fieldValue = fieldValues.pop();
|
||||
const query = createQuery(originalQuery, field, fieldValue);
|
||||
const request = createRequest(query);
|
||||
request['height'] = imageHeight;
|
||||
request['width'] = imageWidth;
|
||||
request['thumbnailMaxWidth'] = 300;
|
||||
request['thumbnailMaxHeight'] = 200;
|
||||
|
||||
const success = function(response){
|
||||
data.dashboard.tiles.push({
|
||||
fieldValue: fieldValue,
|
||||
thumbnailUrl: response.thumbnailUrl,
|
||||
imageUrl: response.imageUrl
|
||||
});
|
||||
createDashboardItem(fieldValues, originalQuery, field, imageHeight, imageWidth);
|
||||
};
|
||||
const error = function(e) {
|
||||
var errorMessage = '';
|
||||
if (e.status == 404){
|
||||
// skip
|
||||
}
|
||||
else if (e.status == 503){
|
||||
errorMessage = "Too many parallel requests.";
|
||||
}
|
||||
else{
|
||||
errorMessage = "FAILED: " + JSON.parse(e.responseText).message;
|
||||
}
|
||||
hideLoadingIcon();
|
||||
if (errorMessage) {
|
||||
data.dashboard.tiles.push({
|
||||
fieldValue: fieldValue,
|
||||
error: errorMessage
|
||||
});
|
||||
}
|
||||
createDashboardItem(fieldValues, originalQuery, field, imageHeight, imageWidth);
|
||||
};
|
||||
postJson("plots", request, success, error);
|
||||
}
|
||||
}
|
||||
|
||||
function postJson(url, requestData, successCallback, errorCallback) {
|
||||
|
||||
$.ajax({
|
||||
|
||||
@@ -19,7 +19,10 @@
|
||||
<div id="app">
|
||||
<search-bar v-bind="{ 'searchBar': searchBar }"></search-bar>
|
||||
<navigation-bar v-bind="{ 'searchBar': searchBar }"></navigation-bar>
|
||||
<result-view v-bind="{ 'searchBar': searchBar, 'resultView': resultView }"></result-view>
|
||||
<div id="result">
|
||||
<result-view v-bind="{ 'searchBar': searchBar, 'resultView': resultView }"></result-view>
|
||||
<result-view-dashboard v-bind="{ 'dashboard': dashboard }"></result-view-dashboard>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user