filter gallery items by max value and average
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -264,3 +264,7 @@ input:required:invalid {
|
|||||||
.clickable {
|
.clickable {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.time {
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
@@ -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({
|
||||||
|
|||||||
Reference in New Issue
Block a user