filter gallery items by max value and average

This commit is contained in:
2018-05-19 14:43:16 +02:00
parent 38a46a9d46
commit 3d71befbad
3 changed files with 118 additions and 15 deletions

View File

@@ -92,7 +92,7 @@ public class PlotResponseStats {
dataSerie.getMaxValue(), dataSerie.getAverage())); dataSerie.getMaxValue(), dataSerie.getAverage()));
} }
final double average = DataSeriesStats.average(dataSeriesStats); final double average = Math.round(DataSeriesStats.average(dataSeriesStats));
return new PlotResponseStats(maxValue, values, plottedValues, average, dataSeriesStats); return new PlotResponseStats(maxValue, values, plottedValues, average, dataSeriesStats);
} }

View File

@@ -264,3 +264,7 @@ input:required:invalid {
.clickable { .clickable {
cursor: pointer; cursor: pointer;
} }
.time {
font-family: monospace;
}

View File

@@ -260,8 +260,31 @@ Vue.component('result-view-gallery-item', {
data.gallery.image = this.galleryItem.imageUrl; data.gallery.image = this.galleryItem.imageUrl;
} }
}, },
computed: {
showItem: function(){
const predicate = data.gallery.filter.threshold.comparator
? function(a, b) { return a <= b; }
: function(a, b) { return a >= b; };
const value = timeUnitToMillis(data.gallery.filter.threshold.value, data.gallery.filter.threshold.unit);
switch(data.gallery.filter.option){
case 'NONE':
return true;
case 'MAX_VALUE':
return predicate(this.galleryItem.stats.maxValue, value);
case 'AVG':
return predicate(this.galleryItem.stats.average, value);
}
throw "unhandled option: " + data.gallery.filter.option;
},
maxValue: function(){
return formatMs(this.galleryItem.stats.maxValue);
},
average: function(){
return formatMs(this.galleryItem.stats.average);
}
},
template: ` template: `
<div class="gallery-item"> <div class="gallery-item" v-if="showItem">
<div class="error-message" v-if="galleryItem.error">{{ galleryItem.error }}</div> <div class="error-message" v-if="galleryItem.error">{{ galleryItem.error }}</div>
<a <a
v-bind:href="galleryItem.imageUrl" v-bind:href="galleryItem.imageUrl"
@@ -273,6 +296,8 @@ Vue.component('result-view-gallery-item', {
@click="showImage" @click="showImage"
/></a> /></a>
<div class="fieldValue">{{ galleryItem.fieldValue }}</div> <div class="fieldValue">{{ galleryItem.fieldValue }}</div>
<div class="fieldStatsMaxValue">Max value: <span class="time">{{ maxValue }}</span></div>
<div class="fieldStatsAverage">Average: <span class="time">{{ average }}</span></div>
</div>` </div>`
}); });
@@ -296,6 +321,10 @@ Vue.component('navigation-bar-gallery', {
// data.gallery.toBeRendered.length > 0 && // data.gallery.toBeRendered.length > 0 &&
return data.gallery.progress.show; return data.gallery.progress.show;
}, },
showThreshold: function (){
const opts = ['MAX_VALUE','AVG'];
return opts.includes(data.gallery.filter.option);
},
percentage: function() { percentage: function() {
if (data.gallery.progress.max > 100){ if (data.gallery.progress.max > 100){
return Math.round(10000*data.gallery.progress.value / data.gallery.progress.max)/100.0; return Math.round(10000*data.gallery.progress.value / data.gallery.progress.max)/100.0;
@@ -320,22 +349,41 @@ Vue.component('navigation-bar-gallery', {
<option value="ASC">asc</option> <option value="ASC">asc</option>
</select> </select>
</div> </div>
<!--
<div class="group"> <div class="group">
<label for="galleryFilter">Filter by:</label> <label for="galleryFilter">Filter by:</label>
<select id="galleryFilter" name="galleryFilter" v-model="gallery.filter"> <select
<option value="NONE">none</option> id="galleryFilter"
<option value="HIGHER_THAN">higher</option> name="galleryFilter"
<option value="LOWER_THAN">lower</option> v-model="gallery.filter.option">
<option value="HIGHER_AVG_THAN">higher avg.</option> <option value="NONE">none</option>
<option value="LOWER_AVG_THAN">lower avg.</option> <option value="MAX_VALUE">max value</option>
<option value="HIGHER_PERCENTILE_THAN">higher percentile</option> <option value="AVG">average</option>
<option value="LOWER_PERCENTILE_THAN">lower percentile</option> </select>
<option value="MORE_THAN">more</option>
<option value="LESS_THAN">less</option> <button
v-show="showThreshold"
@click="gallery.filter.threshold.comparator = !gallery.filter.threshold.comparator"
>{{ gallery.filter.threshold.comparator ? "≤" : "≥" }}</button>
<input
type="number"
class="number-input-1k"
v-show="showThreshold"
v-model="gallery.filter.threshold.value"
min="0"
max="999"
/>
<select
name="galleryFilterThresholdUnit"
v-show="showThreshold"
v-model="gallery.filter.threshold.unit">
<option value="MILLISECONDS" title="milli seconds">milli seconds</option>
<option value="SECONDS" title="seconds">seconds</option>
<option value="MINUTES" title="minutes">minutes</option>
<option value="HOURS" title="hours">hours</option>
<option value="DAYS" title="days">days</option>
</select> </select>
</div> </div>
-->
<div id="galleryControls" class="group" v-if="showProgressBar"> <div id="galleryControls" class="group" v-if="showProgressBar">
<progress <progress
@@ -611,6 +659,10 @@ Vue.component('search-bar', {
'keyOutside': data.searchBar.keyOutside, 'keyOutside': data.searchBar.keyOutside,
'sortyBy': data.gallery.sortBy, 'sortyBy': data.gallery.sortBy,
'sortyOrder': data.gallery.sortOrder, 'sortyOrder': data.gallery.sortOrder,
'filterOption': data.gallery.filter.option,
'filterThresholdValue': data.gallery.filter.threshold.value,
'filterThresholdUnit': data.gallery.filter.threshold.unit,
'filterThresholdComparator': data.gallery.filter.threshold.comparator,
}; };
var link = window.location.origin+ window.location.pathname + "?" + jQuery.param( params ); var link = window.location.origin+ window.location.pathname + "?" + jQuery.param( params );
@@ -843,7 +895,14 @@ var data = {
image: "", image: "",
sortBy: GetURLParameter('sortyBy','MAX_VALUE'), sortBy: GetURLParameter('sortyBy','MAX_VALUE'),
sortOrder: GetURLParameter('sortyOrder','DESC'), sortOrder: GetURLParameter('sortyOrder','DESC'),
filter: "NONE", filter: {
option: GetURLParameter('filterOption', 'NONE'),
threshold: {
value: GetURLParameter('filterThresholdValue','0'),
unit: GetURLParameter('filterThresholdUnit', 'SECONDS'),
comparator: GetURLParameterBoolean('filterThresholdComparator', 'false')
}
},
progress: { progress: {
max: 0, max: 0,
value: 0, value: 0,
@@ -1093,6 +1152,46 @@ function sortTiles() {
} }
} }
function timeUnitToMillis(value, unit)
{
switch(unit){
case 'MILLISECONDS':
return value;
case 'SECONDS':
return value*1000;
case 'MINUTES':
return value*1000*60;
case 'HOURS':
return value*1000*60*60;
case 'DAYS':
return value*1000*60*60*24;
}
throw "unknown unit: " + unit;
}
function formatMs(valueInMs) {
const ms = Math.floor(valueInMs % 1000);
const s = Math.floor((valueInMs / 1000) % 60);
const m = Math.floor((valueInMs / (60*1000)) % 60);
const h = Math.floor(valueInMs / (3600*1000));
var result = "";
if (h != 0) {
result += h+"h ";
}
if (h!= 0 || m != 0) {
result += m+"m ";
}
if (h!= 0 || m != 0 || s != 0) {
result += s+"s ";
result += ms+"ms";
} else {
result += ms+"ms";
}
return result;
}
function postJson(url, requestData, successCallback, errorCallback) { function postJson(url, requestData, successCallback, errorCallback) {
$.ajax({ $.ajax({