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

View File

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

View File

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

View File

@@ -13,6 +13,10 @@ public class PlotRequest {
private int limit = Integer.MAX_VALUE;
private String dateFrom;
private String dateTo;
public String getQuery() {
return query;
}
@@ -65,4 +69,20 @@ public class PlotRequest {
public void setLimit(final int 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;
}
#search-bar .autocomplete, #search-bar .autocomplete ul {
#search-bar .autocomplete {
overflow-y: scroll;
}
#search-bar #search-input {
box-sizing: border-box;
}
#filter-bar {
}

View File

@@ -29,6 +29,13 @@
<option value="FEWEST_VALUES">fewest values</option>
</select>
<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>
</div>
<div id="result-view">

View File

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

View File

@@ -1,7 +1,7 @@
dependencies {
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'

View File

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

View File

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