add date range filter

This commit is contained in:
2017-03-17 11:17:57 +01:00
parent 8cc42916a4
commit 3456177291
11 changed files with 140 additions and 34 deletions

View File

@@ -1,5 +1,13 @@
package org.lucares.pdb.plot.api; package org.lucares.pdb.plot.api;
import java.time.Instant;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZoneOffset;
import org.apache.commons.lang3.StringUtils;
public class PlotSettings { public class PlotSettings {
private String query; private String query;
@@ -13,6 +21,10 @@ public class PlotSettings {
private int limit; private int limit;
private String dateFrom;
private String dateTo;
public String getQuery() { public String getQuery() {
return query; return query;
} }
@@ -60,4 +72,38 @@ public class PlotSettings {
public void setLimit(final int limit) { public void setLimit(final int limit) {
this.limit = limit; this.limit = limit;
} }
public String getDateFrom() {
return dateFrom;
}
public void setDateFrom(final String dateFrom) {
this.dateFrom = dateFrom;
}
public String getDateTo() {
return dateTo;
}
public void setDateTo(final String dateTo) {
this.dateTo = dateTo;
}
public OffsetDateTime dateFrom() {
if (StringUtils.isEmpty(dateFrom)) {
return OffsetDateTime.ofInstant(Instant.ofEpochMilli(Long.MIN_VALUE), ZoneOffset.UTC);
} else {
return LocalDate.parse(dateFrom).atTime(OffsetTime.of(0, 0, 0, 0, ZoneOffset.UTC));
}
}
public OffsetDateTime dateTo() {
if (StringUtils.isEmpty(dateTo)) {
return OffsetDateTime.ofInstant(Instant.ofEpochMilli(Long.MAX_VALUE), ZoneOffset.UTC);
} else {
return LocalDate.parse(dateTo).atTime(OffsetTime.of(23, 59, 59, 999_999_999, ZoneOffset.UTC));
}
}
} }

View File

@@ -17,6 +17,7 @@ import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.lucares.pdb.api.Entry; import org.lucares.pdb.api.Entry;
@@ -53,13 +54,19 @@ public class Plotter {
} }
public File plot(final PlotSettings plotSettings) throws InternalPlottingException { public File plot(final PlotSettings plotSettings) throws InternalPlottingException {
final String tmpSubDir = uniqueDirectoryName();
final Path tmpDir = tmpBaseDir.resolve(tmpSubDir);
try { try {
Files.createDirectories(tmpDir);
final List<DataSeries> dataSeries = new ArrayList<>(); final List<DataSeries> dataSeries = new ArrayList<>();
final String query = plotSettings.getQuery(); final String query = plotSettings.getQuery();
final String groupBy = plotSettings.getGroupBy(); final String groupBy = plotSettings.getGroupBy();
final int height = plotSettings.getHeight(); final int height = plotSettings.getHeight();
final int width = plotSettings.getWidth(); final int width = plotSettings.getWidth();
final OffsetDateTime dateFrom = plotSettings.dateFrom();
final OffsetDateTime dateTo = plotSettings.dateTo();
final Result result = db.get(query, groupBy); final Result result = db.get(query, groupBy);
@@ -70,16 +77,18 @@ public class Plotter {
final Stream<Entry> entries = groupResult.asStream(); final Stream<Entry> entries = groupResult.asStream();
final File dataFile = File.createTempFile("data", ".dat", tmpBaseDir.toFile()); final File dataFile = File.createTempFile("data", ".dat", tmpDir.toFile());
final CsvSummary csvSummary = toCsv(entries, dataFile); final CsvSummary csvSummary = toCsv(entries, dataFile, dateFrom, dateTo);
final String title = title(groupResult.getGroupedBy(), csvSummary.getValues()); final String title = title(groupResult.getGroupedBy(), csvSummary.getValues());
final DataSeries dataSerie = new DataSeries(dataFile, title, csvSummary.getValues()); final DataSeries dataSerie = new DataSeries(dataFile, title, csvSummary.getValues());
if (dataSerie.getValues() > 0) {
dataSeries.add(dataSerie); dataSeries.add(dataSerie);
maxDate = maxDate.compareTo(csvSummary.getMaxDate()) > 0 ? maxDate : csvSummary.getMaxDate(); maxDate = maxDate.compareTo(csvSummary.getMaxDate()) > 0 ? maxDate : csvSummary.getMaxDate();
minDate = minDate.compareTo(csvSummary.getMinDate()) < 0 ? minDate : csvSummary.getMinDate(); minDate = minDate.compareTo(csvSummary.getMinDate()) < 0 ? minDate : csvSummary.getMinDate();
} }
}
sortAndLimit(dataSeries, plotSettings); sortAndLimit(dataSeries, plotSettings);
@@ -96,9 +105,16 @@ public class Plotter {
throw new IllegalStateException("Plotting was interrupted."); throw new IllegalStateException("Plotting was interrupted.");
} catch (final IOException e) { } catch (final IOException e) {
throw new InternalPlottingException("Plotting failed.", e); throw new InternalPlottingException("Plotting failed.", e);
} finally {
FileUtils.delete(tmpDir);
} }
} }
private String uniqueDirectoryName() {
return OffsetDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH_mm_ss")) + "_"
+ UUID.randomUUID().toString();
}
private String getFormatX(final OffsetDateTime minDate, final OffsetDateTime maxDate) { private String getFormatX(final OffsetDateTime minDate, final OffsetDateTime maxDate) {
if (minDate.until(maxDate, ChronoUnit.WEEKS) > 1) { if (minDate.until(maxDate, ChronoUnit.WEEKS) > 1) {
@@ -176,10 +192,13 @@ public class Plotter {
} }
} }
private static CsvSummary toCsv(final Stream<Entry> entries, final File dataFile) throws IOException { private static CsvSummary toCsv(final Stream<Entry> entries, final File dataFile, final OffsetDateTime dateFrom,
final OffsetDateTime dateTo) throws IOException {
final long start = System.nanoTime(); final long start = System.nanoTime();
int count = 0; int count = 0;
final long fromEpochMilli = dateFrom.toInstant().toEpochMilli();
final long toEpochMilli = dateTo.toInstant().toEpochMilli();
OffsetDateTime maxDate = OffsetDateTime.MIN; OffsetDateTime maxDate = OffsetDateTime.MIN;
OffsetDateTime minDate = OffsetDateTime.MAX; OffsetDateTime minDate = OffsetDateTime.MAX;
final int separator = ','; final int separator = ',';
@@ -190,8 +209,9 @@ public class Plotter {
while (it.hasNext()) { while (it.hasNext()) {
final Entry entry = it.next(); final Entry entry = it.next();
final String value = String.valueOf(entry.getValue()); if (fromEpochMilli <= entry.getEpochMilli() && entry.getEpochMilli() <= toEpochMilli) {
final OffsetDateTime date = entry.getDate(); final OffsetDateTime date = entry.getDate();
final String value = String.valueOf(entry.getValue());
final String formattedDate = date.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); final String formattedDate = date.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
output.write(formattedDate); output.write(formattedDate);
output.write(separator); output.write(separator);
@@ -203,6 +223,7 @@ public class Plotter {
minDate = minDate.compareTo(date) < 0 ? minDate : date; minDate = minDate.compareTo(date) < 0 ? minDate : date;
} }
} }
}
System.out.println("wrote " + count + " values to csv in: " + (System.nanoTime() - start) / 1_000_000.0 + "ms"); System.out.println("wrote " + count + " values to csv in: " + (System.nanoTime() - start) / 1_000_000.0 + "ms");
return new CsvSummary(count, maxDate, minDate); return new CsvSummary(count, maxDate, minDate);

View File

@@ -94,10 +94,10 @@ public class PdbController implements HardcodedValues, CollectionUtils {
produces = MediaType.APPLICATION_JSON_UTF8_VALUE // produces = MediaType.APPLICATION_JSON_UTF8_VALUE //
) )
@ResponseBody @ResponseBody
List<String> fields(@RequestParam(name = "query") final String query) { List<String> fields() {
try { try {
final List<String> fields = db.getDb().getFields(query); final List<String> fields = db.getDb().getFields();
return fields; return fields;

View File

@@ -16,6 +16,8 @@ class PlotSettingsTransformer {
result.setWidth(request.getWidth()); result.setWidth(request.getWidth());
result.setLimit(request.getLimit()); result.setLimit(request.getLimit());
result.setLimitBy(toLimit(request.getLimitBy())); result.setLimitBy(toLimit(request.getLimitBy()));
result.setDateFrom(request.getDateFrom());
result.setDateTo(request.getDateTo());
return result; return result;
} }

View File

@@ -13,6 +13,10 @@ public class PlotRequest {
private int limit = Integer.MAX_VALUE; private int limit = Integer.MAX_VALUE;
private String dateFrom;
private String dateTo;
public String getQuery() { public String getQuery() {
return query; return query;
} }
@@ -65,4 +69,20 @@ public class PlotRequest {
public void setLimit(final int limit) { public void setLimit(final int limit) {
this.limit = limit; this.limit = limit;
} }
public String getDateFrom() {
return dateFrom;
}
public void setDateFrom(final String dateFrom) {
this.dateFrom = dateFrom;
}
public String getDateTo() {
return dateTo;
}
public void setDateTo(final String dateTo) {
this.dateTo = dateTo;
}
} }

View File

@@ -45,10 +45,14 @@ html, body {
background-color: #AAA; background-color: #AAA;
} }
#search-bar .autocomplete, #search-bar .autocomplete ul { #search-bar .autocomplete {
overflow-y: scroll; overflow-y: scroll;
} }
#search-bar #search-input {
box-sizing: border-box;
}
#filter-bar { #filter-bar {
} }

View File

@@ -29,6 +29,13 @@
<option value="FEWEST_VALUES">fewest values</option> <option value="FEWEST_VALUES">fewest values</option>
</select> </select>
<input type="number" id="search-limit-value" name="search-limit-value" min="1" max="1000000" value="10" style="display: none;"/> <input type="number" id="search-limit-value" name="search-limit-value" min="1" max="1000000" value="10" style="display: none;"/>
<label>From Date:</label>
<input id="search-date-from" type="date">
<label>To Date:</label>
<input id="search-date-to" type="date">
<button id="search-submit"><i class="fa fa-area-chart"> Plot</i></button> <button id="search-submit"><i class="fa fa-area-chart"> Plot</i></button>
</div> </div>
<div id="result-view"> <div id="result-view">

View File

@@ -3,12 +3,12 @@ $(document).ready(function(){
$('#search-submit').click(plot); $('#search-submit').click(plot);
renderFields(); renderGroupBy();
$('#search-limit-by').change(function () { $('#search-limit-by').change(function () {
var optionSelected = $(this).find("option:selected"); var optionSelected = $(this).find("option:selected");
var valueSelected = optionSelected.val(); var valueSelected = optionSelected.val();
console.log(valueSelected);
if (valueSelected == "NO_LIMIT"){ if (valueSelected == "NO_LIMIT"){
$('#search-limit-value').hide(); $('#search-limit-value').hide();
}else{ }else{
@@ -23,6 +23,9 @@ $(document).ready(function(){
var caretIndex = document.getElementById('search-input').selectionStart; var caretIndex = document.getElementById('search-input').selectionStart;
return 'caretIndex=' + caretIndex + '&query'; return 'caretIndex=' + caretIndex + '&query';
}, },
_Pre: function() {
return encodeURI(this.Input.value);
},
_Post: function(response) { _Post: function(response) {
var result = []; var result = [];
var responseObject = JSON.parse(response); var responseObject = JSON.parse(response);
@@ -40,10 +43,9 @@ $(document).ready(function(){
}); });
}); });
function renderFields() function renderGroupBy()
{ {
var request = {}; var request = {};
request['query'] = $('#search-input').val();
var success = function(response){ var success = function(response){
@@ -85,6 +87,8 @@ function plot(event){
request['groupBy'] = $('#search-group-by').val(); request['groupBy'] = $('#search-group-by').val();
request['limitBy'] = $('#search-limit-by').val(); request['limitBy'] = $('#search-limit-by').val();
request['limit'] = parseInt($('#search-limit-value').val()); request['limit'] = parseInt($('#search-limit-value').val());
request['dateFrom'] = $('#search-date-from').val();
request['dateTo'] = $('#search-date-to').val();
var success = function(response){ var success = function(response){

View File

@@ -1,7 +1,7 @@
dependencies { dependencies {
compile project(':pdb-api') compile project(':pdb-api')
compile 'org.lucares:ludb:1.0.20170207192657' compile 'org.lucares:ludb:1.0.20170218180719'
compile 'com.fasterxml.jackson.core:jackson-databind:2.8.6' compile 'com.fasterxml.jackson.core:jackson-databind:2.8.6'

View File

@@ -8,13 +8,15 @@ import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.List; import java.util.List;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FileUtils { public class FileUtils {
private static final Logger LOGGER = Logger.getLogger(FileUtils.class.getCanonicalName());
private static final Logger LOGGER = LoggerFactory.getLogger(FileUtils.class);
private static final class RecursiveDeleter extends SimpleFileVisitor<Path> { private static final class RecursiveDeleter extends SimpleFileVisitor<Path> {
@@ -22,7 +24,7 @@ public class FileUtils {
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
Files.delete(file); Files.delete(file);
LOGGER.info("deleted: " + file.toFile().getAbsolutePath()); LOGGER.trace("deleted: {}", file);
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
@@ -31,7 +33,7 @@ public class FileUtils {
public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException { public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException {
Files.delete(dir); Files.delete(dir);
LOGGER.info("deleted: " + dir.toFile().getAbsolutePath()); LOGGER.trace("deleted: {}", dir);
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
@@ -44,14 +46,13 @@ public class FileUtils {
while (attempt <= maxAttempts) { while (attempt <= maxAttempts) {
try { try {
LOGGER.info( LOGGER.debug("deleting '{}' attempt {} of {}", path.toFile().getAbsolutePath(), attempt, maxAttempts);
"deleting '" + path.toFile().getAbsolutePath() + "' attempt " + attempt + " of " + maxAttempts);
Files.walkFileTree(path, new RecursiveDeleter()); Files.walkFileTree(path, new RecursiveDeleter());
break; break;
} catch (final IOException e) { } catch (final IOException e) {
final String msg = "failed to delete '" + path.toFile().getAbsolutePath() + "' on attempt " + attempt final String msg = "failed to delete '" + path.toFile().getAbsolutePath() + "' on attempt " + attempt
+ " of " + maxAttempts; + " of " + maxAttempts;
LOGGER.log(Level.WARNING, msg, e); LOGGER.warn(msg, e);
} }
attempt++; attempt++;
} }

View File

@@ -182,8 +182,9 @@ public class PerformanceDb implements AutoCloseable, CollectionUtils {
return db.proposeTagForQuery(query, caretIndex); return db.proposeTagForQuery(query, caretIndex);
} }
public List<String> getFields(final String query) { public List<String> getFields() {
final List<Field> fields = db.getAvailableFieldsForQuery(query);
final List<Field> fields = db.getAvailableFields();
return map(fields, Field::getName); return map(fields, Field::getName);
} }