accumulating Meter periods + code clean

This commit is contained in:
Patrick Haßel 2025-02-25 10:19:50 +01:00
parent ee9d510316
commit 685436a316
9 changed files with 43 additions and 25 deletions

View File

@ -8,19 +8,19 @@ import java.time.*;
public class Aligned { public class Aligned {
@NonNull @NonNull
public final Alignment interval; public final Alignment alignment;
@NonNull @NonNull
public final ZonedDateTime date; public final ZonedDateTime date;
public Aligned(@NonNull final Alignment interval, @NonNull final ZonedDateTime date) { public Aligned(@NonNull final Alignment alignment, @NonNull final ZonedDateTime date) {
this.interval = interval; this.alignment = alignment;
this.date = interval.align.apply(date); this.date = alignment.align.apply(date);
} }
@NonNull @NonNull
public Aligned minus(final long offset) { public Aligned minus(final long offset) {
return new Aligned(interval, interval.plus.apply(date, -offset)); return new Aligned(alignment, alignment.plus.apply(date, -offset));
} }
} }

View File

@ -59,7 +59,7 @@ public class Graph {
public final int maxLabelWidth; public final int maxLabelWidth;
public Graph(@NonNull final SeriesDto series, @NonNull final List<GraphPoint> points, final @NonNull Aligned begin, final @NonNull Aligned end, final int width, final int height, final int border) { public Graph(@NonNull final SeriesDto series, @NonNull final List<GraphPoint> points, @NonNull final Aligned begin, @NonNull final Aligned end, final int width, final int height, final int border) {
this.series = series; this.series = series;
this.begin = begin; this.begin = begin;
this.end = end; this.end = end;
@ -129,7 +129,7 @@ public class Graph {
return image; return image;
} }
private void yLabel(final Graphics2D g, final double value, @Nullable final Stroke stroke, @Nullable final Color color) { private void yLabel(@NonNull final Graphics2D g, final double value, @Nullable final Stroke stroke, @Nullable final Color color) {
final String string = series.format(value); final String string = series.format(value);
final int offset = maxLabelWidth - g.getFontMetrics().stringWidth(string); final int offset = maxLabelWidth - g.getFontMetrics().stringWidth(string);
final int y = height - ((int) Math.round((value - valueMin) * valueScale) + border); final int y = height - ((int) Math.round((value - valueMin) * valueScale) + border);
@ -141,6 +141,7 @@ public class Graph {
} }
} }
@NonNull
private Function<GraphPoint, Point> toPoint(final long minuteMin, final double minuteScale, final double valueMin, final double valueScale) { private Function<GraphPoint, Point> toPoint(final long minuteMin, final double minuteScale, final double valueMin, final double valueScale) {
return point -> { return point -> {
final long minuteEpoch = point.getDate().toEpochSecond() / 60; final long minuteEpoch = point.getDate().toEpochSecond() / 60;

View File

@ -19,10 +19,10 @@ public class GraphController {
private final GraphService graphService; private final GraphService graphService;
@GetMapping(path = "{seriesId}/{width}/{height}/{intervalName}/{offset}/{duration}", produces = "image/png") @GetMapping(path = "{seriesId}/{width}/{height}/{alignmentName}/{offset}/{duration}", produces = "image/png")
public void graph(@PathVariable final long seriesId, final HttpServletResponse response, @PathVariable final int width, @PathVariable final int height, @PathVariable final String intervalName, @PathVariable final long offset, @PathVariable final long duration) throws IOException { public void graph(@PathVariable final long seriesId, final HttpServletResponse response, @PathVariable final int width, @PathVariable final int height, @PathVariable final String alignmentName, @PathVariable final long offset, @PathVariable final long duration) throws IOException {
final Alignment interval = Alignment.valueOf(intervalName); final Alignment alignment = Alignment.valueOf(alignmentName);
final Aligned end = interval.align(ZonedDateTime.now()).minus(offset); final Aligned end = alignment.align(ZonedDateTime.now()).minus(offset);
final Aligned begin = end.minus(duration); final Aligned begin = end.minus(duration);
final Graph graph = graphService.getGraph(seriesId, begin, end, width, height, 10); final Graph graph = graphService.getGraph(seriesId, begin, end, width, height, 10);
final BufferedImage image = graph.draw(); final BufferedImage image = graph.draw();

View File

@ -11,4 +11,12 @@ public class GraphPoint {
public final double value; public final double value;
@NonNull
public GraphPoint plus(@NonNull final GraphPoint other) {
if (this.date.compareTo(other.date) != 0) {
throw new RuntimeException();
}
return new GraphPoint(date, value + other.value);
}
} }

View File

@ -15,6 +15,7 @@ import org.springframework.stereotype.*;
import org.springframework.transaction.annotation.*; import org.springframework.transaction.annotation.*;
import java.util.*; import java.util.*;
import java.util.stream.*;
@Slf4j @Slf4j
@Service @Service
@ -71,15 +72,23 @@ public class MeterService {
@NonNull @NonNull
public List<GraphPoint> getPoints(@NonNull final SeriesDto series, @NonNull final Aligned begin, @NonNull final Aligned end) { public List<GraphPoint> getPoints(@NonNull final SeriesDto series, @NonNull final Aligned begin, @NonNull final Aligned end) {
final List<? extends MeterValue> graphPoints = switch (begin.interval) { final List<? extends MeterValue> graphPoints = switch (begin.alignment) {
case FIVE -> meterFiveRepository.findAllByIdMeterSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqual(series.id, begin.date, end.date); case FIVE -> meterFiveRepository.findAllByIdMeterSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqualOrderByIdDate(series.id, begin.date, end.date);
case HOUR -> meterHourRepository.findAllByIdMeterSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqual(series.id, begin.date, end.date); case HOUR -> meterHourRepository.findAllByIdMeterSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqualOrderByIdDate(series.id, begin.date, end.date);
case DAY -> meterDayRepository.findAllByIdMeterSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqual(series.id, begin.date, end.date); case DAY -> meterDayRepository.findAllByIdMeterSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqualOrderByIdDate(series.id, begin.date, end.date);
case WEEK -> meterWeekRepository.findAllByIdMeterSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqual(series.id, begin.date, end.date); case WEEK -> meterWeekRepository.findAllByIdMeterSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqualOrderByIdDate(series.id, begin.date, end.date);
case MONTH -> meterMonthRepository.findAllByIdMeterSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqual(series.id, begin.date, end.date); case MONTH -> meterMonthRepository.findAllByIdMeterSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqualOrderByIdDate(series.id, begin.date, end.date);
case YEAR -> meterYearRepository.findAllByIdMeterSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqual(series.id, begin.date, end.date); case YEAR -> meterYearRepository.findAllByIdMeterSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqualOrderByIdDate(series.id, begin.date, end.date);
}; };
return graphPoints.stream().map(v -> new GraphPoint(v.getId().getDate(), v.getMax() - v.getMin())).toList(); final List<GraphPoint> points = graphPoints.stream().map(v -> new GraphPoint(v.getId().getDate(), v.getMax() - v.getMin())).collect(Collectors.toCollection(LinkedList::new));
for (int i = 0; i < points.size() - 1; i++) {
if (points.get(i).date.compareTo(points.get(i + 1).date) == 0) {
final GraphPoint first = points.remove(i);
final GraphPoint second = points.remove(i + 1);
points.add(i, first.plus(second));
}
}
return points;
} }
} }

View File

@ -50,9 +50,9 @@ public abstract class MeterValue {
@Column(nullable = false) @Column(nullable = false)
private ZonedDateTime date; private ZonedDateTime date;
public Id(@NonNull final Meter meter, @NonNull final ZonedDateTime date, @NonNull final Alignment interval) { public Id(@NonNull final Meter meter, @NonNull final ZonedDateTime date, @NonNull final Alignment alignment) {
this.meter = meter; this.meter = meter;
this.date = interval.align(date).date; this.date = alignment.align(date).date;
} }
} }

View File

@ -9,6 +9,6 @@ import java.util.*;
@NoRepositoryBean @NoRepositoryBean
public interface MeterValueRepository<T extends MeterValue> extends ListCrudRepository<T, MeterValue.Id> { public interface MeterValueRepository<T extends MeterValue> extends ListCrudRepository<T, MeterValue.Id> {
List<T> findAllByIdMeterSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqual(long id, @NonNull ZonedDateTime begin, @NonNull ZonedDateTime end); List<T> findAllByIdMeterSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqualOrderByIdDate(long id, @NonNull ZonedDateTime begin, @NonNull ZonedDateTime end);
} }

View File

@ -57,9 +57,9 @@ public abstract class Varying {
@Column(nullable = false) @Column(nullable = false)
private ZonedDateTime date; private ZonedDateTime date;
public Id(@NonNull final Series series, @NonNull final ZonedDateTime date, @NonNull final Alignment interval) { public Id(@NonNull final Series series, @NonNull final ZonedDateTime date, @NonNull final Alignment alignment) {
this.series = series; this.series = series;
this.date = interval.align(date).date; this.date = alignment.align(date).date;
} }
} }

View File

@ -61,7 +61,7 @@ public class VaryingService {
@NonNull @NonNull
public List<GraphPoint> getPoints(@NonNull final SeriesDto series, @NonNull final Aligned begin, @NonNull final Aligned end) { public List<GraphPoint> getPoints(@NonNull final SeriesDto series, @NonNull final Aligned begin, @NonNull final Aligned end) {
final List<? extends Varying> graphPoints = switch (begin.interval) { final List<? extends Varying> graphPoints = switch (begin.alignment) {
case FIVE -> varyingFiveRepository.findAllByIdSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqual(series.id, begin.date, end.date); case FIVE -> varyingFiveRepository.findAllByIdSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqual(series.id, begin.date, end.date);
case HOUR -> varyingHourRepository.findAllByIdSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqual(series.id, begin.date, end.date); case HOUR -> varyingHourRepository.findAllByIdSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqual(series.id, begin.date, end.date);
case DAY -> varyingDayRepository.findAllByIdSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqual(series.id, begin.date, end.date); case DAY -> varyingDayRepository.findAllByIdSeriesIdAndIdDateGreaterThanEqualAndIdDateLessThanEqual(series.id, begin.date, end.date);