replace startDate + dateRange with start and end date
The new datetimepicker can be used to specify date ranges. We no longer need to define a start date and a range. This simplifies the code for zooming and shifting considerably.
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
package org.lucares.pdb.plot.api;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
|
||||||
|
public class DateTimeRange {
|
||||||
|
private final OffsetDateTime start;
|
||||||
|
private final OffsetDateTime end;
|
||||||
|
|
||||||
|
public DateTimeRange(final OffsetDateTime start, final OffsetDateTime end) {
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OffsetDateTime getStart() {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OffsetDateTime getEnd() {
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return start + "-" + end;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
package org.lucares.pdb.plot.api;
|
package org.lucares.pdb.plot.api;
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
public class PlotSettings {
|
public class PlotSettings {
|
||||||
|
|
||||||
@@ -30,9 +29,7 @@ public class PlotSettings {
|
|||||||
|
|
||||||
private int limit;
|
private int limit;
|
||||||
|
|
||||||
private String dateFrom;
|
private String dateRangeAsString;
|
||||||
|
|
||||||
private String dateRange;
|
|
||||||
|
|
||||||
private AxisScale yAxisScale;
|
private AxisScale yAxisScale;
|
||||||
|
|
||||||
@@ -110,68 +107,24 @@ public class PlotSettings {
|
|||||||
this.limit = limit;
|
this.limit = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDateFrom() {
|
|
||||||
return dateFrom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDateFrom(final String dateFrom) {
|
|
||||||
this.dateFrom = dateFrom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDateRange() {
|
public String getDateRange() {
|
||||||
return dateRange;
|
return dateRangeAsString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDateRange(final String dateRange) {
|
public void setDateRange(final String dateRangeAsString) {
|
||||||
this.dateRange = dateRange;
|
this.dateRangeAsString = dateRangeAsString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OffsetDateTime dateFrom() {
|
public DateTimeRange dateRange() {
|
||||||
|
|
||||||
if (StringUtils.isEmpty(dateFrom)) {
|
final String[] startEnd = dateRangeAsString.split(Pattern.quote(" - "));
|
||||||
|
Preconditions.checkArgument(startEnd.length == 2, "invalid date range");
|
||||||
|
|
||||||
return OffsetDateTime.ofInstant(Instant.ofEpochMilli(Long.MIN_VALUE), ZoneOffset.UTC);
|
final OffsetDateTime startDate = LocalDateTime.parse(startEnd[0], DATE_FORMAT).atOffset(ZoneOffset.UTC);
|
||||||
} else {
|
final OffsetDateTime endDate = LocalDateTime.parse(startEnd[1], DATE_FORMAT).atOffset(ZoneOffset.UTC);
|
||||||
return LocalDateTime.parse(dateFrom, DATE_FORMAT).atOffset(ZoneOffset.UTC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public OffsetDateTime dateTo() {
|
return new DateTimeRange(startDate, endDate);
|
||||||
|
|
||||||
if (StringUtils.isEmpty(dateRange)) {
|
|
||||||
return OffsetDateTime.ofInstant(Instant.ofEpochMilli(Long.MAX_VALUE), ZoneOffset.UTC);
|
|
||||||
} else {
|
|
||||||
final int period = Integer.parseInt(dateRange.split(" ")[0]);
|
|
||||||
final ChronoUnit unit = toChronoUnit(dateRange.split(" ")[1]);
|
|
||||||
|
|
||||||
return dateFrom().plus(period, unit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ChronoUnit toChronoUnit(final String string) {
|
|
||||||
|
|
||||||
switch (string) {
|
|
||||||
case "second":
|
|
||||||
case "seconds":
|
|
||||||
return ChronoUnit.SECONDS;
|
|
||||||
case "minute":
|
|
||||||
case "minutes":
|
|
||||||
return ChronoUnit.MINUTES;
|
|
||||||
case "hour":
|
|
||||||
case "hours":
|
|
||||||
return ChronoUnit.HOURS;
|
|
||||||
case "day":
|
|
||||||
case "days":
|
|
||||||
return ChronoUnit.DAYS;
|
|
||||||
case "week":
|
|
||||||
case "weeks":
|
|
||||||
return ChronoUnit.WEEKS;
|
|
||||||
case "month":
|
|
||||||
case "months":
|
|
||||||
return ChronoUnit.MONTHS;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException(string + " is an unknown chrono unit");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setYAxisScale(final AxisScale axisScale) {
|
public void setYAxisScale(final AxisScale axisScale) {
|
||||||
@@ -186,7 +139,7 @@ public class PlotSettings {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "PlotSettings [query=" + query + ", height=" + height + ", width=" + width + ", thumbnailMaxWidth="
|
return "PlotSettings [query=" + query + ", height=" + height + ", width=" + width + ", thumbnailMaxWidth="
|
||||||
+ thumbnailMaxWidth + ", thumbnailMaxHeight=" + thumbnailMaxHeight + ", groupBy=" + groupBy
|
+ thumbnailMaxWidth + ", thumbnailMaxHeight=" + thumbnailMaxHeight + ", groupBy=" + groupBy
|
||||||
+ ", limitBy=" + limitBy + ", limit=" + limit + ", dateFrom=" + dateFrom + ", dateRange=" + dateRange
|
+ ", limitBy=" + limitBy + ", limit=" + limit + ", dateRangeAsString=" + dateRangeAsString
|
||||||
+ ", yAxisScale=" + yAxisScale + ", aggregate=" + aggregate + ", yRangeMin=" + yRangeMin
|
+ ", yAxisScale=" + yAxisScale + ", aggregate=" + aggregate + ", yRangeMin=" + yRangeMin
|
||||||
+ ", yRangeMax=" + yRangeMax + ", yRangeUnit=" + yRangeUnit + ", keyOutside=" + keyOutside
|
+ ", yRangeMax=" + yRangeMax + ", yRangeUnit=" + yRangeUnit + ", keyOutside=" + keyOutside
|
||||||
+ ", generateThumbnail=" + generateThumbnail + "]";
|
+ ", generateThumbnail=" + generateThumbnail + "]";
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.lucares.pdb.api.GroupResult;
|
|||||||
import org.lucares.pdb.api.Result;
|
import org.lucares.pdb.api.Result;
|
||||||
import org.lucares.pdb.api.Tags;
|
import org.lucares.pdb.api.Tags;
|
||||||
import org.lucares.pdb.plot.api.CustomAggregator;
|
import org.lucares.pdb.plot.api.CustomAggregator;
|
||||||
|
import org.lucares.pdb.plot.api.DateTimeRange;
|
||||||
import org.lucares.pdb.plot.api.Limit;
|
import org.lucares.pdb.plot.api.Limit;
|
||||||
import org.lucares.pdb.plot.api.PlotSettings;
|
import org.lucares.pdb.plot.api.PlotSettings;
|
||||||
import org.lucares.pdb.plot.api.TimeRangeUnitInternal;
|
import org.lucares.pdb.plot.api.TimeRangeUnitInternal;
|
||||||
@@ -78,8 +79,9 @@ public class ScatterPlot {
|
|||||||
final List<String> groupBy = plotSettings.getGroupBy();
|
final List<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 DateTimeRange dateRange = plotSettings.dateRange();
|
||||||
final OffsetDateTime dateTo = plotSettings.dateTo();
|
final OffsetDateTime dateFrom = dateRange.getStart();
|
||||||
|
final OffsetDateTime dateTo = dateRange.getEnd();
|
||||||
|
|
||||||
final Result result = db.get(query, groupBy);
|
final Result result = db.get(query, groupBy);
|
||||||
|
|
||||||
@@ -117,7 +119,7 @@ public class ScatterPlot {
|
|||||||
final GnuplotSettings gnuplotSettings = new GnuplotSettings(outputFile);
|
final GnuplotSettings gnuplotSettings = new GnuplotSettings(outputFile);
|
||||||
gnuplotSettings.setHeight(height);
|
gnuplotSettings.setHeight(height);
|
||||||
gnuplotSettings.setWidth(width);
|
gnuplotSettings.setWidth(width);
|
||||||
defineXAxis(gnuplotSettings, plotSettings.dateFrom(), plotSettings.dateTo());
|
defineXAxis(gnuplotSettings, plotSettings.dateRange());
|
||||||
|
|
||||||
gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale());
|
gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale());
|
||||||
gnuplotSettings.setAggregate(plotSettings.getAggregate());
|
gnuplotSettings.setAggregate(plotSettings.getAggregate());
|
||||||
@@ -134,7 +136,7 @@ public class ScatterPlot {
|
|||||||
final GnuplotSettings gnuplotSettings = new GnuplotSettings(thumbnail);
|
final GnuplotSettings gnuplotSettings = new GnuplotSettings(thumbnail);
|
||||||
gnuplotSettings.setHeight(plotSettings.getThumbnailMaxHeight());
|
gnuplotSettings.setHeight(plotSettings.getThumbnailMaxHeight());
|
||||||
gnuplotSettings.setWidth(plotSettings.getThumbnailMaxWidth());
|
gnuplotSettings.setWidth(plotSettings.getThumbnailMaxWidth());
|
||||||
defineXAxis(gnuplotSettings, plotSettings.dateFrom(), plotSettings.dateTo());
|
defineXAxis(gnuplotSettings, plotSettings.dateRange());
|
||||||
|
|
||||||
gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale());
|
gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale());
|
||||||
gnuplotSettings.setAggregate(plotSettings.getAggregate());
|
gnuplotSettings.setAggregate(plotSettings.getAggregate());
|
||||||
@@ -169,9 +171,10 @@ public class ScatterPlot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void defineXAxis(final GnuplotSettings gnuplotSettings, final OffsetDateTime minDate,
|
private void defineXAxis(final GnuplotSettings gnuplotSettings, final DateTimeRange dateTimeRange) {
|
||||||
final OffsetDateTime maxDate) {
|
|
||||||
|
|
||||||
|
final OffsetDateTime minDate = dateTimeRange.getStart();
|
||||||
|
final OffsetDateTime maxDate = dateTimeRange.getEnd();
|
||||||
String formatX;
|
String formatX;
|
||||||
int rotateX;
|
int rotateX;
|
||||||
String formattedMinDate;
|
String formattedMinDate;
|
||||||
|
|||||||
@@ -150,8 +150,7 @@ public class PdbController implements HardcodedValues, PropertyKeys {
|
|||||||
@RequestParam(name = "groupBy[]", defaultValue = "") final List<String> aGroupBy,
|
@RequestParam(name = "groupBy[]", defaultValue = "") final List<String> aGroupBy,
|
||||||
@RequestParam(name = "limitBy.number", defaultValue = "10") final int limit,
|
@RequestParam(name = "limitBy.number", defaultValue = "10") final int limit,
|
||||||
@RequestParam(name = "limitBy.selected", defaultValue = "NO_LIMIT") final Limit limitBy,
|
@RequestParam(name = "limitBy.selected", defaultValue = "NO_LIMIT") final Limit limitBy,
|
||||||
@RequestParam(name = "dateFrom", defaultValue = "") final String dateFrom,
|
@RequestParam(name = "dateRange") final String dateRange,
|
||||||
@RequestParam(name = "dateRange", defaultValue = "1 week") final String dateRange,
|
|
||||||
@RequestParam(name = "axisScale", defaultValue = "LINEAR") final AxisScale axisScale,
|
@RequestParam(name = "axisScale", defaultValue = "LINEAR") final AxisScale axisScale,
|
||||||
@RequestParam(name = "aggregate", defaultValue = "NONE") final Aggregate aggregate,
|
@RequestParam(name = "aggregate", defaultValue = "NONE") final Aggregate aggregate,
|
||||||
@RequestParam(name = "keyOutside", defaultValue = "false") final boolean keyOutside,
|
@RequestParam(name = "keyOutside", defaultValue = "false") final boolean keyOutside,
|
||||||
@@ -163,6 +162,10 @@ public class PdbController implements HardcodedValues, PropertyKeys {
|
|||||||
throw new BadRequest("The query must not be empty!");
|
throw new BadRequest("The query must not be empty!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(dateRange)) {
|
||||||
|
throw new BadRequest("The parameter 'dateRange' must be set.");
|
||||||
|
}
|
||||||
|
|
||||||
final PlotSettings plotSettings = new PlotSettings();
|
final PlotSettings plotSettings = new PlotSettings();
|
||||||
plotSettings.setQuery(query);
|
plotSettings.setQuery(query);
|
||||||
plotSettings.setGroupBy(aGroupBy);
|
plotSettings.setGroupBy(aGroupBy);
|
||||||
@@ -170,7 +173,6 @@ public class PdbController implements HardcodedValues, PropertyKeys {
|
|||||||
plotSettings.setWidth(hidth);
|
plotSettings.setWidth(hidth);
|
||||||
plotSettings.setLimit(limit);
|
plotSettings.setLimit(limit);
|
||||||
plotSettings.setLimitBy(limitBy);
|
plotSettings.setLimitBy(limitBy);
|
||||||
plotSettings.setDateFrom(dateFrom);
|
|
||||||
plotSettings.setDateRange(dateRange);
|
plotSettings.setDateRange(dateRange);
|
||||||
plotSettings.setYAxisScale(axisScale);
|
plotSettings.setYAxisScale(axisScale);
|
||||||
plotSettings.setAggregate(PlotSettingsTransformer.toAggregateInternal(aggregate));
|
plotSettings.setAggregate(PlotSettingsTransformer.toAggregateInternal(aggregate));
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ class PlotSettingsTransformer {
|
|||||||
result.setWidth(request.getWidth());
|
result.setWidth(request.getWidth());
|
||||||
result.setLimit(request.getLimit());
|
result.setLimit(request.getLimit());
|
||||||
result.setLimitBy(request.getLimitBy());
|
result.setLimitBy(request.getLimitBy());
|
||||||
result.setDateFrom(request.getDateFrom());
|
|
||||||
result.setDateRange(request.getDateRange());
|
result.setDateRange(request.getDateRange());
|
||||||
result.setYAxisScale(request.getAxisScale());
|
result.setYAxisScale(request.getAxisScale());
|
||||||
result.setAggregate(toAggregateInternal(request.getAggregate()));
|
result.setAggregate(toAggregateInternal(request.getAggregate()));
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ public class PlotRequest {
|
|||||||
|
|
||||||
private int limit = Integer.MAX_VALUE;
|
private int limit = Integer.MAX_VALUE;
|
||||||
|
|
||||||
private String dateFrom;
|
|
||||||
|
|
||||||
private String dateRange;
|
private String dateRange;
|
||||||
|
|
||||||
private Aggregate aggregate = Aggregate.NONE;
|
private Aggregate aggregate = Aggregate.NONE;
|
||||||
@@ -107,22 +105,11 @@ public class PlotRequest {
|
|||||||
this.limit = limit;
|
this.limit = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDateFrom() {
|
|
||||||
return dateFrom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDateFrom(final String dateFrom) {
|
|
||||||
this.dateFrom = dateFrom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDateRange() {
|
public String getDateRange() {
|
||||||
return dateRange;
|
return dateRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDateRange(final String dateRange) {
|
public void setDateRange(final String dateRange) {
|
||||||
if (!dateRange.matches("\\d+ (second|minute|hour|day|week|month)s?")) {
|
|
||||||
throw new IllegalArgumentException(dateRange + " is not a valid range");
|
|
||||||
}
|
|
||||||
this.dateRange = dateRange;
|
this.dateRange = dateRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -138,8 +138,8 @@ textarea {
|
|||||||
width: 4em;
|
width: 4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input_date {
|
#search-date-range {
|
||||||
max-width: 10em;
|
width: 38ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#add-filter {
|
#add-filter {
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ function ffHasParentWithId(el, id) {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DATE_PATTERN = "YYYY-MM-DD HH:mm:ss"; // for moment-JS
|
||||||
|
|
||||||
window.onload=function(){
|
window.onload=function(){
|
||||||
|
|
||||||
const gnuplotLMargin = 110; // The left margin configured for gnuplot
|
const gnuplotLMargin = 110; // The left margin configured for gnuplot
|
||||||
@@ -24,6 +26,8 @@ moment.locale('en', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Vue.config.keyCodes.arrowUp = 38;
|
Vue.config.keyCodes.arrowUp = 38;
|
||||||
Vue.config.keyCodes.arrowDown = 40;
|
Vue.config.keyCodes.arrowDown = 40;
|
||||||
|
|
||||||
@@ -225,23 +229,22 @@ Vue.component('result-view', {
|
|||||||
return x > gnuplotLMargin && x < imageWith - gnuplotRMargin;
|
return x > gnuplotLMargin && x < imageWith - gnuplotRMargin;
|
||||||
},
|
},
|
||||||
drag_start: function(event) {
|
drag_start: function(event) {
|
||||||
|
event.preventDefault();
|
||||||
if (event.buttons == 1 && this.isInPlot(event.x) && !data.searchBar.imageLastUsedParams.keyOutside) {
|
if (event.buttons == 1 && this.isInPlot(event.x) && !data.searchBar.imageLastUsedParams.keyOutside) {
|
||||||
//console.log("drag-start " +event.x+ " " + event.buttons);
|
|
||||||
this.in_drag_mode = true;
|
this.in_drag_mode = true;
|
||||||
this.drag_start_x = event.x;
|
this.drag_start_x = event.x;
|
||||||
this.drag_end_x = event.x;
|
this.drag_end_x = event.x;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dragging: function(event) {
|
dragging: function(event) {
|
||||||
|
|
||||||
if (this.in_drag_mode && event.buttons == 1 && this.isInPlot(event.x) && !data.searchBar.imageLastUsedParams.keyOutside){
|
if (this.in_drag_mode && event.buttons == 1 && this.isInPlot(event.x) && !data.searchBar.imageLastUsedParams.keyOutside){
|
||||||
//console.log("dragging " + event.layerX+ " " + event.x + " button: " + event.buttons);
|
|
||||||
this.drag_end_x = event.x;
|
this.drag_end_x = event.x;
|
||||||
|
|
||||||
const left = this.drag_start_x < this.drag_end_x ? this.drag_start_x : this.drag_end_x;
|
const left = this.drag_start_x < this.drag_end_x ? this.drag_start_x : this.drag_end_x;
|
||||||
const width = Math.abs(this.drag_start_x - this.drag_end_x);
|
const width = Math.abs(this.drag_start_x - this.drag_end_x);
|
||||||
|
|
||||||
this.zoomInSliderStyle="position: absolute; left: "+left+"px; width: "+width+"px; top:"+gnuplotTMargin+"px; bottom: "+gnuplotBMargin+"px;";
|
this.zoomInSliderStyle="position: absolute; left: "+left+"px; width: "+width+"px; top:"+gnuplotTMargin+"px; bottom: "+gnuplotBMargin+"px;";
|
||||||
//console.log(this.zoomInSliderStyle);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
drag_stop: function(event) {
|
drag_stop: function(event) {
|
||||||
@@ -251,9 +254,7 @@ Vue.component('result-view', {
|
|||||||
|
|
||||||
// Zoom in if the selected area has some arbitrary minimal size
|
// Zoom in if the selected area has some arbitrary minimal size
|
||||||
if (Math.abs(this.drag_start_x - this.drag_end_x) > 10) {
|
if (Math.abs(this.drag_start_x - this.drag_end_x) > 10) {
|
||||||
const dateFrom = data.searchBar.imageLastUsedParams.dateFrom;
|
const dateRange = parseDateRange(data.searchBar.imageLastUsedParams.dateRange);
|
||||||
const dateRange = data.searchBar.imageLastUsedParams.dateRange;
|
|
||||||
|
|
||||||
|
|
||||||
const startPxInImage = Math.min(this.drag_start_x, this.drag_end_x);
|
const startPxInImage = Math.min(this.drag_start_x, this.drag_end_x);
|
||||||
const endPxInImage = Math.max(this.drag_start_x, this.drag_end_x);
|
const endPxInImage = Math.max(this.drag_start_x, this.drag_end_x);
|
||||||
@@ -264,16 +265,10 @@ Vue.component('result-view', {
|
|||||||
const endPxWithinPlotArea = endPxInImage - gnuplotLMargin;
|
const endPxWithinPlotArea = endPxInImage - gnuplotLMargin;
|
||||||
|
|
||||||
const startPercentOfDateRange = startPxWithinPlotArea / widthPlotArea;
|
const startPercentOfDateRange = startPxWithinPlotArea / widthPlotArea;
|
||||||
const intervalPercentOfDateRange = (endPxWithinPlotArea- startPxWithinPlotArea) / widthPlotArea;
|
const endPercentOfDateRange = 1-endPxWithinPlotArea / widthPlotArea;
|
||||||
|
|
||||||
const dateRangeInSeconds = this.dateRangeToSeconds(dateRange);
|
shiftDate(data.searchBar.imageLastUsedParams.dateRange, startPercentOfDateRange, -1*endPercentOfDateRange);
|
||||||
const newStartDate = this.shiftDateBySeconds(dateFrom, dateRangeInSeconds * startPercentOfDateRange);
|
|
||||||
const newDateRangeInSeconds = Math.max(60, dateRangeInSeconds * intervalPercentOfDateRange);
|
|
||||||
const newDateRange = Math.ceil(newDateRangeInSeconds) + " seconds";
|
|
||||||
|
|
||||||
console.log("new range: "+newStartDate+" with interval "+newDateRange);
|
|
||||||
data.searchBar.dateFrom = newStartDate;
|
|
||||||
data.searchBar.dateRange = newDateRange;
|
|
||||||
plotCurrent();
|
plotCurrent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -283,51 +278,6 @@ Vue.component('result-view', {
|
|||||||
this.drag_start_x = 0;
|
this.drag_start_x = 0;
|
||||||
this.drag_end_x = 0;
|
this.drag_end_x = 0;
|
||||||
this.zoomInSliderStyle="display: none;";
|
this.zoomInSliderStyle="display: none;";
|
||||||
},
|
|
||||||
shiftDateBySeconds: function(date, shiftInSeconds) {
|
|
||||||
var oldDate = Date.parse(date);
|
|
||||||
var newDate = oldDate.add({seconds: shiftInSeconds});
|
|
||||||
return newDate.toString("yyyy-MM-dd HH:mm:ss");
|
|
||||||
},
|
|
||||||
dateRangeToSeconds: function(dateRange){
|
|
||||||
var tokens = dateRange.split(/ +/,2);
|
|
||||||
|
|
||||||
var newValue = -1;
|
|
||||||
if(tokens.length == 2)
|
|
||||||
{
|
|
||||||
var value = parseInt(tokens[0]);
|
|
||||||
var period = tokens[1];
|
|
||||||
switch (period) {
|
|
||||||
case "second":
|
|
||||||
case "seconds":
|
|
||||||
newValue = value;
|
|
||||||
break;
|
|
||||||
case "minute":
|
|
||||||
case "minutes":
|
|
||||||
newValue = value * 60;
|
|
||||||
break;
|
|
||||||
case "hour":
|
|
||||||
case "hours":
|
|
||||||
newValue = value * 60*60;
|
|
||||||
break;
|
|
||||||
case "day":
|
|
||||||
case "days":
|
|
||||||
newValue = value * 24*60*60;
|
|
||||||
break;
|
|
||||||
case "week":
|
|
||||||
case "weeks":
|
|
||||||
newValue = value * 7*24*60*60;
|
|
||||||
break;
|
|
||||||
case "month":
|
|
||||||
case "months":
|
|
||||||
newValue = value * 30*7*24*60*60;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.log("unhandled value: "+ period);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newValue;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -546,155 +496,33 @@ Vue.component('navigation-bar', {
|
|||||||
},
|
},
|
||||||
zoomIn: function()
|
zoomIn: function()
|
||||||
{
|
{
|
||||||
this.shiftDate(0.25);
|
shiftDate(data.searchBar.dateRange, 0.25, -0.25);
|
||||||
this.zoom(0.5);
|
|
||||||
plotCurrent();
|
plotCurrent();
|
||||||
},
|
},
|
||||||
zoomOut: function()
|
zoomOut: function()
|
||||||
{
|
{
|
||||||
this.shiftDate(-0.5);
|
shiftDate(data.searchBar.dateRange, -0.5, 0.5);
|
||||||
this.zoom(2);
|
|
||||||
plotCurrent();
|
plotCurrent();
|
||||||
},
|
},
|
||||||
dateLeftShift: function()
|
dateLeftShift: function()
|
||||||
{
|
{
|
||||||
this.shiftDate(-1);
|
shiftDate(data.searchBar.dateRange, -1, -1);
|
||||||
plotCurrent();
|
plotCurrent();
|
||||||
},
|
},
|
||||||
dateHalfLeftShift: function()
|
dateHalfLeftShift: function()
|
||||||
{
|
{
|
||||||
this.shiftDate(-0.5);
|
shiftDate(data.searchBar.dateRange, -0.5, -0.5);
|
||||||
plotCurrent();
|
plotCurrent();
|
||||||
},
|
},
|
||||||
dateHalfRightShift: function()
|
dateHalfRightShift: function()
|
||||||
{
|
{
|
||||||
this.shiftDate(0.5);
|
shiftDate(data.searchBar.dateRange, 0.5, 0.5);
|
||||||
plotCurrent();
|
plotCurrent();
|
||||||
},
|
},
|
||||||
dateRightShift: function()
|
dateRightShift: function()
|
||||||
{
|
{
|
||||||
this.shiftDate(1);
|
shiftDate(data.searchBar.dateRange, 1, 1);
|
||||||
plotCurrent();
|
plotCurrent();
|
||||||
},
|
|
||||||
zoom: function(factor)
|
|
||||||
{
|
|
||||||
if (!$('#search-date-range').is(":invalid")) {
|
|
||||||
|
|
||||||
var dateRange = data.searchBar.dateRange;
|
|
||||||
var tokens = dateRange.split(/ +/,2);
|
|
||||||
|
|
||||||
if(tokens.length == 2)
|
|
||||||
{
|
|
||||||
var value = parseInt(tokens[0]);
|
|
||||||
var period = tokens[1];
|
|
||||||
|
|
||||||
var newValue = value*factor;
|
|
||||||
while (newValue != Math.round(newValue)){
|
|
||||||
|
|
||||||
switch (period) {
|
|
||||||
case "second":
|
|
||||||
case "seconds":
|
|
||||||
if (value == 1) {
|
|
||||||
// we reached the smallest range
|
|
||||||
}
|
|
||||||
else if (value % 2 == 1){
|
|
||||||
value = value -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "minute":
|
|
||||||
case "minutes":
|
|
||||||
value = value * 60;
|
|
||||||
period = "seconds";
|
|
||||||
break;
|
|
||||||
case "hour":
|
|
||||||
case "hours":
|
|
||||||
value = value * 60;
|
|
||||||
period = "minutes";
|
|
||||||
break;
|
|
||||||
case "day":
|
|
||||||
case "days":
|
|
||||||
value = value * 24;
|
|
||||||
period = "hours";
|
|
||||||
break;
|
|
||||||
case "week":
|
|
||||||
case "weeks":
|
|
||||||
value = value * 7;
|
|
||||||
period = "days";
|
|
||||||
break;
|
|
||||||
case "month":
|
|
||||||
case "months":
|
|
||||||
value = value * 30;
|
|
||||||
period = "days";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.log("unhandled value: "+ period);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
newValue = value*factor
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
data.searchBar.dateRange = newValue + " " + period;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
shiftDate: function(directionalFactor)
|
|
||||||
{
|
|
||||||
var dateBefore = Date.parse(data.searchBar.dateFrom);
|
|
||||||
var newDate = this.shiftByInterval(dateBefore, directionalFactor);
|
|
||||||
data.searchBar.dateFrom = newDate.toString("yyyy-MM-dd HH:mm:ss");
|
|
||||||
},
|
|
||||||
shiftByInterval: function(date, directionalFactor)
|
|
||||||
{
|
|
||||||
if (!$('#search-date-range').is(":invalid")) {
|
|
||||||
|
|
||||||
var dateRange = data.searchBar.dateRange;
|
|
||||||
var tokens = dateRange.split(/ +/,2);
|
|
||||||
|
|
||||||
if(tokens.length == 2)
|
|
||||||
{
|
|
||||||
var value = parseInt(tokens[0]);
|
|
||||||
var period = tokens[1];
|
|
||||||
var config = {};
|
|
||||||
|
|
||||||
value = directionalFactor * value;
|
|
||||||
|
|
||||||
switch (period) {
|
|
||||||
case "second":
|
|
||||||
case "seconds":
|
|
||||||
config = { seconds: value };
|
|
||||||
break;
|
|
||||||
case "minute":
|
|
||||||
case "minutes":
|
|
||||||
config = { minutes: value };
|
|
||||||
break;
|
|
||||||
case "hour":
|
|
||||||
case "hours":
|
|
||||||
config = { minutes: 60*value };
|
|
||||||
break;
|
|
||||||
case "day":
|
|
||||||
case "days":
|
|
||||||
config = { days: value };
|
|
||||||
break;
|
|
||||||
case "week":
|
|
||||||
case "weeks":
|
|
||||||
config = { days: 7*value };
|
|
||||||
break;
|
|
||||||
case "month":
|
|
||||||
case "months":
|
|
||||||
config = { days: 30*value };
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newDate = date.add(config);
|
|
||||||
return newDate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return date;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -733,10 +561,8 @@ Vue.component('group-by-item', {
|
|||||||
Vue.component('search-bar', {
|
Vue.component('search-bar', {
|
||||||
props: ['searchBar'],
|
props: ['searchBar'],
|
||||||
mounted: function() {
|
mounted: function() {
|
||||||
$('#search-date-from').daterangepicker({
|
$('#search-date-range').daterangepicker({
|
||||||
timePicker: true,
|
timePicker: true,
|
||||||
singleDatePicker: true,
|
|
||||||
startDate: Date.parse(data.searchBar.dateFrom),
|
|
||||||
minDate: "2017-01-01",
|
minDate: "2017-01-01",
|
||||||
maxDate: moment(),
|
maxDate: moment(),
|
||||||
maxYear: parseInt(moment().format('YYYY'),10),
|
maxYear: parseInt(moment().format('YYYY'),10),
|
||||||
@@ -758,15 +584,18 @@ Vue.component('search-bar', {
|
|||||||
'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
|
'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
$('#search-date-from').on('apply.daterangepicker', function(ev, picker) {
|
$('#search-date-range').on('apply.daterangepicker', function(ev, picker) {
|
||||||
data.searchBar.dateFrom = picker.startDate.format('YYYY-MM-DD HH:mm:ss');
|
setDateRange(picker.startDate, picker.endDate);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
// whenever searchBar.dateFrom changes, this function will run
|
// whenever searchBar.dateRange changes, this function will run
|
||||||
'searchBar.dateFrom': function (newDateFrom, oldDateFrom) {
|
'searchBar.dateRange': function (newdateRangeAsString, olddateRangeAsString) {
|
||||||
const newDate = Date.parse(newDateFrom);
|
if (newdateRangeAsString) {
|
||||||
$('#search-date-from').data('daterangepicker').setStartDate(newDate);
|
const newdateRange = parseDateRange(newdateRangeAsString);
|
||||||
|
$('#search-date-range').data('daterangepicker').setStartDate(newdateRange.startDate);
|
||||||
|
$('#search-date-range').data('daterangepicker').setEndDate(newdateRange.endDate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -825,7 +654,6 @@ Vue.component('search-bar', {
|
|||||||
'splitByKeys.selected': data.searchBar.splitByKeys.selected,
|
'splitByKeys.selected': data.searchBar.splitByKeys.selected,
|
||||||
'limitBy.selected': data.searchBar.limitBy.selected,
|
'limitBy.selected': data.searchBar.limitBy.selected,
|
||||||
'limitBy.number': data.searchBar.limitBy.number,
|
'limitBy.number': data.searchBar.limitBy.number,
|
||||||
'dateFrom': data.searchBar.dateFrom,
|
|
||||||
'dateRange': data.searchBar.dateRange,
|
'dateRange': data.searchBar.dateRange,
|
||||||
'axisScale': data.searchBar.axisScale,
|
'axisScale': data.searchBar.axisScale,
|
||||||
'aggregate': data.searchBar.aggregate,
|
'aggregate': data.searchBar.aggregate,
|
||||||
@@ -888,40 +716,13 @@ Vue.component('search-bar', {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="group">
|
<div class="group">
|
||||||
<label for="search-date-from">From Date:</label>
|
<label for="search-date-range">Date Range:</label>
|
||||||
<input type='text'
|
<input type='text'
|
||||||
id="search-date-from"
|
|
||||||
v-model="searchBar.dateFrom"
|
|
||||||
required="required"
|
|
||||||
pattern="\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2]\\d|3[0-1]) [0-2]\\d:[0-5]\\d:[0-5]\\d"
|
|
||||||
/>
|
|
||||||
<!--
|
|
||||||
<input
|
|
||||||
id="search-date-from"
|
|
||||||
v-model="searchBar.dateFrom"
|
|
||||||
class="input_date"
|
|
||||||
type="text"
|
|
||||||
required="required"
|
|
||||||
pattern="\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2]\\d|3[0-1]) [0-2]\\d:[0-5]\\d:[0-5]\\d" />-->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="group">
|
|
||||||
<label for="search-date-range">Interval:</label>
|
|
||||||
<input
|
|
||||||
id="search-date-range"
|
id="search-date-range"
|
||||||
v-model="searchBar.dateRange"
|
v-model="searchBar.dateRange"
|
||||||
type="text"
|
|
||||||
list="ranges"
|
|
||||||
required="required"
|
required="required"
|
||||||
pattern="\\d+ (second|minute|hour|day|week|month)s?">
|
pattern="\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2]\\d|3[0-1]) [0-2]\\d:[0-5]\\d:[0-5]\\d - \\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2]\\d|3[0-1]) [0-2]\\d:[0-5]\\d:[0-5]\\d"
|
||||||
<datalist id="ranges">
|
/>
|
||||||
<option value="60 seconds"/>
|
|
||||||
<option value="5 minutes"/>
|
|
||||||
<option value="1 hour"/>
|
|
||||||
<option value="1 day"/>
|
|
||||||
<option value="1 week"/>
|
|
||||||
<option value="1 month"/>
|
|
||||||
</datalist>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="group">
|
<div class="group">
|
||||||
@@ -1049,8 +850,7 @@ var data = {
|
|||||||
'selected': GetURLParameter('limitBy.selected','NO_LIMIT'),
|
'selected': GetURLParameter('limitBy.selected','NO_LIMIT'),
|
||||||
'number': GetURLParameter('limitBy.number',10)
|
'number': GetURLParameter('limitBy.number',10)
|
||||||
},
|
},
|
||||||
dateFrom: GetURLParameter('dateFrom', Date.now().add({ days: -7 }).toString("yyyy-MM-dd HH:mm:ss")), // '2018-01-05 09:03'
|
dateRange: GetURLParameter('dateRange', moment().add({ days: -6 }).startOf('day').format(DATE_PATTERN)+ ' - '+ moment().endOf('day').format(DATE_PATTERN)), // '2018-01-05 09:03:03'
|
||||||
dateRange: GetURLParameter('dateRange','1 week'),
|
|
||||||
axisScale: GetURLParameter('axisScale','LOG10'),
|
axisScale: GetURLParameter('axisScale','LOG10'),
|
||||||
aggregate: GetURLParameter('aggregate','NONE'),
|
aggregate: GetURLParameter('aggregate','NONE'),
|
||||||
yRange: {
|
yRange: {
|
||||||
@@ -1096,6 +896,46 @@ var data = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function parseDateRange(dateRangeAsString){
|
||||||
|
|
||||||
|
if (dateRangeAsString) {
|
||||||
|
const startDate = moment(dateRangeAsString.slice(0, 19));
|
||||||
|
const endDate = moment(dateRangeAsString.slice(22, 41));
|
||||||
|
|
||||||
|
return {
|
||||||
|
startDate: startDate,
|
||||||
|
endDate: endDate,
|
||||||
|
duration: moment.duration(endDate.diff(startDate))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDateRange(startDate, endDate) {
|
||||||
|
const formattedStartDate = startDate.format(DATE_PATTERN);
|
||||||
|
const formattedEndDate = endDate.format(DATE_PATTERN);
|
||||||
|
|
||||||
|
data.searchBar.dateRange = formattedStartDate+" - "+formattedEndDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zoom in/out or shift date by adding factorStartDate*dateRangeInSeconds seconds to the start date
|
||||||
|
* and factorEndDate*dateRangeInSeconds seconds to the end date.
|
||||||
|
*
|
||||||
|
* shiftDate(dateRangeAsString, 0.25, -0.25) will zoom in, making the range half its size
|
||||||
|
* shiftDate(dateRangeAsString, -0.5, 0.5) will zoom out, making the range double its size
|
||||||
|
* shiftDate(dateRangeAsString, -0.5, -0.5) will move the range by half its size to older values
|
||||||
|
* shiftDate(dateRangeAsString, 1, 1) will move the range by its size to newer values
|
||||||
|
*/
|
||||||
|
function shiftDate(dateRange, factorStartDate, factorEndDate)
|
||||||
|
{
|
||||||
|
const dateRangeParsed = parseDateRange(dateRange);
|
||||||
|
const dateRangeInSeconds = dateRangeParsed.duration.asSeconds();
|
||||||
|
|
||||||
|
const newStartDate = dateRangeParsed.startDate.add({seconds: dateRangeInSeconds*factorStartDate});
|
||||||
|
const newEndDate = dateRangeParsed.endDate.add({seconds: dateRangeInSeconds*factorEndDate});
|
||||||
|
|
||||||
|
setDateRange(newStartDate, newEndDate);
|
||||||
|
}
|
||||||
|
|
||||||
function showLoadingIcon()
|
function showLoadingIcon()
|
||||||
{
|
{
|
||||||
@@ -1165,7 +1005,6 @@ function createRequest(query, generateThumbnail){
|
|||||||
request['groupBy'] = groupBy();
|
request['groupBy'] = groupBy();
|
||||||
request['limitBy'] = data.searchBar.limitBy.selected;
|
request['limitBy'] = data.searchBar.limitBy.selected;
|
||||||
request['limit'] = parseInt(data.searchBar.limitBy.number);
|
request['limit'] = parseInt(data.searchBar.limitBy.number);
|
||||||
request['dateFrom'] = data.searchBar.dateFrom;
|
|
||||||
request['dateRange'] = data.searchBar.dateRange;
|
request['dateRange'] = data.searchBar.dateRange;
|
||||||
request['axisScale'] = data.searchBar.axisScale;
|
request['axisScale'] = data.searchBar.axisScale;
|
||||||
request['aggregate'] = data.searchBar.aggregate;
|
request['aggregate'] = data.searchBar.aggregate;
|
||||||
@@ -1219,7 +1058,6 @@ function updateImageLink(query) {
|
|||||||
'splitByKeys.selected': data.searchBar.splitByKeys.selected,
|
'splitByKeys.selected': data.searchBar.splitByKeys.selected,
|
||||||
'limitBy.selected': data.searchBar.limitBy.selected,
|
'limitBy.selected': data.searchBar.limitBy.selected,
|
||||||
'limitBy.number': data.searchBar.limitBy.number,
|
'limitBy.number': data.searchBar.limitBy.number,
|
||||||
'dateFrom': data.searchBar.dateFrom,
|
|
||||||
'dateRange': data.searchBar.dateRange,
|
'dateRange': data.searchBar.dateRange,
|
||||||
'axisScale': data.searchBar.axisScale,
|
'axisScale': data.searchBar.axisScale,
|
||||||
'aggregate': data.searchBar.aggregate,
|
'aggregate': data.searchBar.aggregate,
|
||||||
|
|||||||
Reference in New Issue
Block a user