dashboard #1

Merged
andi merged 118 commits from dashboard into master 2024-09-29 06:47:35 +00:00
6 changed files with 108 additions and 40 deletions
Showing only changes of commit a69fe09464 - Show all commits

View File

@@ -7,6 +7,7 @@ import { Overlay } from "@angular/cdk/overlay";
import { DateTime, Duration } from "luxon";
import { DateValue } from '../components/datepicker/date-picker.component';
import { Observable } from 'rxjs';
@Component({
selector: 'pdb-plot-view',
@@ -190,11 +191,11 @@ export class PlotViewComponent {
}
zoomRange(range: SelectionRange) {
this.shiftDate(this.config?.dateRange.value!, range.startPercentOfDateRange, range.endPercentOfDateRange-1);
this.shiftDate(this.config?.dateRange!, range.startPercentOfDateRange, range.endPercentOfDateRange-1);
}
zoomWithDateAnchor(dateAnchor: DateAnchor){
this.shiftDateByAnchor(this.config?.dateRange.value!, dateAnchor.cursorPercentOfDateRange, dateAnchor.zoomFactor);
this.shiftDateByAnchor(this.config?.dateRange!, dateAnchor.cursorPercentOfDateRange, dateAnchor.zoomFactor);
}
zoomByScroll(event: WheelEvent) {
@@ -295,18 +296,27 @@ export class PlotViewComponent {
* shiftDateByAnchor(dateRangeAsString, 0.20, 0.5) zooms in by 50%, so that the date that was at 20% before the zoom is still at 20% after the zoom
* shiftDateByAnchor(dateRangeAsString, 0.33, 2) zooms out by 50%, so that the date that was at 33% before the zoom is still at 33% after the zoom
*/
shiftDateByAnchor(dateRange:string, anchorInPercentOfDateRange:number, zoomFactor:number)
shiftDateByAnchor(dateValue:DateValue, anchorInPercentOfDateRange:number, zoomFactor:number)
{
const dateRangeParsed = this.parseDateRange(dateRange);
const dateRangeInSeconds = Math.floor(dateRangeParsed.duration.toMillis()/1000);
debugger;
const dateRangeParsed = this.parseDateRange(dateValue);
dateRangeParsed.subscribe({
next: (dataRange: DateRange) => {
const dateRangeInSeconds = Math.floor(dataRange.duration.toMillis()/1000);
const anchorTimestampInSeconds = dateRangeParsed.startDate.plus(Math.floor(dateRangeInSeconds*anchorInPercentOfDateRange)*1000);
const anchorTimestampInSeconds = dataRange.startDate.plus(Math.floor(dateRangeInSeconds*anchorInPercentOfDateRange)*1000);
const newDateRangeInSeconds = dateRangeInSeconds * zoomFactor;
const newStartDate = anchorTimestampInSeconds.minus(newDateRangeInSeconds*anchorInPercentOfDateRange*1000);
const newEndDate = newStartDate.plus({seconds: newDateRangeInSeconds});;
this.setDateRange(newStartDate, newEndDate);
},
error: (err: any) => {
window.console.error("failed to parse DateValue into DateRange: ", err);
}
})
}
/**
@@ -318,9 +328,11 @@ export class PlotViewComponent {
* 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
*/
shiftDate(dateRange: string, factorStartDate: number, factorEndDate: number)
shiftDate(dateValue: DateValue, factorStartDate: number, factorEndDate: number)
{
const dateRangeParsed = this.parseDateRange(dateRange);
debugger;
this.parseDateRange(dateValue).subscribe(
dateRangeParsed => {
const dateRangeInSeconds = Math.floor(dateRangeParsed.duration.toMillis()/1000);
const newStartDate = dateRangeParsed.startDate.plus({seconds: dateRangeInSeconds*factorStartDate});
@@ -328,8 +340,13 @@ export class PlotViewComponent {
this.setDateRange(newStartDate, newEndDate);
}
);
}
parseDateRange(dateRangeAsString : string) : DateRange {
parseDateRange(dateValue : DateValue) : Observable<DateRange> {
return this.service.toDateRange(dateValue);
/*
.pipe(map((dateRangeAsString:string) => {
const startDate = DateTime.fromFormat(dateRangeAsString.slice(0, 19), this.DATE_PATTERN );
const endDate = DateTime.fromFormat(dateRangeAsString.slice(22, 41), this.DATE_PATTERN );
@@ -339,6 +356,8 @@ export class PlotViewComponent {
endDate: endDate,
duration: endDate.diff(startDate),
};
}));
*/
}

View File

@@ -3,11 +3,16 @@ import { HttpClient, HttpParams } from "@angular/common/http";
import { Observable } from "rxjs";
import { map } from "rxjs/operators";
import { DateValue } from "./components/datepicker/date-picker.component";
import { DateRange } from "./plot-view/plot-view.component";
import { DateTime } from "luxon";
@Injectable({
providedIn: "root",
})
export class PlotService {
readonly DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss";
plotTypes: Array<PlotType>;
constructor(private http: HttpClient) {
@@ -253,6 +258,20 @@ export class PlotService {
),
);
}
toDateRange(dateValue: DateValue): Observable<DateRange> {
return this.http.post<{start: string, end:string, startEpochMilli: number, endEpochMilli: number}>("//" + window.location.hostname+":" + window.location.port +"/api/dates",dateValue)
.pipe(map((data) => {
const startDate = DateTime.fromFormat(data.start.slice(0, -1), this.DATE_PATTERN );
const endDate = DateTime.fromFormat(data.end.slice(0, -1), this.DATE_PATTERN );
return {
startDate: startDate,
endDate: endDate,
duration: endDate.diff(startDate),
};
}));
}
}
export class PlotType {

View File

@@ -1,16 +1,22 @@
package org.lucares.pdb.plot.api;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.lucares.pdb.api.DateTimeRange;
import org.lucares.utils.Preconditions;
public class DateTimeRangeParser {
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static DateTimeRange parse(final OffsetDateTime offsetTime, final String datePeriod) {
final String[] startEnd = datePeriod.split(Pattern.quote("/"));
@@ -122,4 +128,16 @@ public class DateTimeRangeParser {
throw new IllegalArgumentException("invalid input: " + timeDefinition);
}
public static DateTimeRange parseAbsolute(final String dateRangeAsString) {
final String[] startEnd = dateRangeAsString.split(Pattern.quote(" - "));
Preconditions.checkEqual(startEnd.length, 2, "invalid date range: ''{0}''", dateRangeAsString);
final String startString = startEnd[0];
final String endString = startEnd[1];
final OffsetDateTime start = LocalDateTime.parse(startString, DATE_FORMAT).atOffset(ZoneOffset.UTC);
final OffsetDateTime end = LocalDateTime.parse(endString, DATE_FORMAT).atOffset(ZoneOffset.UTC);
return new DateTimeRange(start, end);
}
}

View File

@@ -1,19 +1,15 @@
package org.lucares.pdb.plot.api;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
import java.util.regex.Pattern;
import org.lucares.pdb.api.DateTimeRange;
import org.lucares.recommind.logs.GnuplotAxis;
import org.lucares.recommind.logs.GnuplotSettings;
import org.lucares.utils.Preconditions;
public class PlotSettings {
@@ -96,12 +92,7 @@ public class PlotSettings {
final DateTimeRange dateTimeRange = DateTimeRangeParser.parse(OffsetDateTime.now(), dateValue.getValue());
return dateTimeRange;
case ABSOLUTE:
final String[] startEnd = dateValue.getValue().split(Pattern.quote(" - "));
Preconditions.checkEqual(startEnd.length, 2, "invalid date range: ''{0}''", dateValue);
final OffsetDateTime startDate = LocalDateTime.parse(startEnd[0], DATE_FORMAT).atOffset(ZoneOffset.UTC);
final OffsetDateTime endDate = LocalDateTime.parse(startEnd[1], DATE_FORMAT).atOffset(ZoneOffset.UTC);
return new DateTimeRange(startDate, endDate);
return DateTimeRangeParser.parseAbsolute(dateValue.getValue());
}
throw new UnsupportedOperationException();

View File

@@ -3,6 +3,8 @@ package org.lucares.pdbui;
import java.io.IOException;
import java.nio.file.Path;
import java.text.Collator;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -26,6 +28,9 @@ import org.lucares.pdb.api.DateTimeRange;
import org.lucares.pdb.api.QueryWithCaretMarker;
import org.lucares.pdb.api.QueryWithCaretMarker.ResultMode;
import org.lucares.pdb.datastore.Proposal;
import org.lucares.pdb.plot.api.DateTimeRangeParser;
import org.lucares.pdb.plot.api.DateValue;
import org.lucares.pdb.plot.api.DateValue.DateType;
import org.lucares.pdb.plot.api.PlotSettings;
import org.lucares.pdbui.domain.AutocompleteProposal;
import org.lucares.pdbui.domain.AutocompleteProposalByValue;
@@ -345,6 +350,22 @@ public class PdbController implements HardcodedValues, PropertyKeys {
return result;
}
@RequestMapping(path = "/dates", //
method = RequestMethod.POST, //
consumes = MediaType.APPLICATION_JSON_VALUE, //
produces = MediaType.APPLICATION_JSON_VALUE //
)
@ResponseBody
public DateTimeRange dates(@RequestBody final DateValue dateValue) {
final DateType type = dateValue.getType();
final DateTimeRange result = switch (type) {
case RELATIVE -> DateTimeRangeParser.parse(OffsetDateTime.now(ZoneId.of("UTC")), dateValue.getValue());
case QUICK -> DateTimeRangeParser.parse(OffsetDateTime.now(ZoneId.of("UTC")), dateValue.getValue());
case ABSOLUTE -> DateTimeRangeParser.parseAbsolute(dateValue.getValue());
};
return result;
}
@PostMapping(path = "/data", consumes = MediaType.MULTIPART_MIXED_VALUE)
@ResponseBody
@ResponseStatus(code = HttpStatus.CREATED)