From f28a67a5c159c76877b70bc2a883d20a1cfd5d16 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Sun, 20 Oct 2019 10:16:25 +0200 Subject: [PATCH] make it possible to render any combination of plots --- .../pdb/plot/api/AggreateInternal.java | 5 - .../org/lucares/pdb/plot/api}/Aggregate.java | 4 +- .../pdb/plot/api/AggregateHandler.java | 19 ++- .../plot/api/AggregateHandlerCollection.java | 64 ++++++++++ .../plot/api/AggregatedDataCollection.java | 22 ++++ .../pdb/plot/api/AggregatorCollection.java | 29 +++++ ...umulativeDistributionCustomAggregator.java | 5 + .../api/CumulativeDistributionHandler.java | 61 +++++---- .../pdb/plot/api/CustomAggregator.java | 2 + .../lucares/pdb/plot/api/NullAggregate.java | 32 ----- .../pdb/plot/api/NullCustomAggregator.java | 16 --- .../plot/api/ParallelRequestsAggregate.java | 62 +++++----- .../plot/api/ParallelRequestsAggregator.java | 5 + .../lucares/pdb/plot/api/PlotSettings.java | 12 +- .../pdb/plot/api/ScatterAggregateHandler.java | 38 +++--- .../pdb/plot/api/ScatterAggregator.java | 5 + .../lucares/recommind/logs/CsvSummary.java | 8 +- .../lucares/recommind/logs/DataSeries.java | 4 +- .../recommind/logs/FileBackedDataSeries.java | 4 +- .../recommind/logs/GnuplotFileGenerator.java | 6 +- .../recommind/logs/GnuplotSettings.java | 12 +- .../org/lucares/recommind/logs/Plotter.java | 12 +- .../java/org/lucares/pdbui/PdbController.java | 7 +- .../pdbui/PlotSettingsTransformer.java | 116 ++++++++++-------- .../org/lucares/pdbui/domain/PlotRequest.java | 12 +- pdb-ui/src/main/resources/resources/js/ui.js | 2 +- 26 files changed, 321 insertions(+), 243 deletions(-) delete mode 100644 pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggreateInternal.java rename {pdb-ui/src/main/java/org/lucares/pdbui/domain => pdb-plotting/src/main/java/org/lucares/pdb/plot/api}/Aggregate.java (82%) create mode 100644 pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregateHandlerCollection.java create mode 100644 pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregatedDataCollection.java create mode 100644 pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregatorCollection.java delete mode 100644 pdb-plotting/src/main/java/org/lucares/pdb/plot/api/NullAggregate.java delete mode 100644 pdb-plotting/src/main/java/org/lucares/pdb/plot/api/NullCustomAggregator.java diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggreateInternal.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggreateInternal.java deleted file mode 100644 index c6ab8a7..0000000 --- a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggreateInternal.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.lucares.pdb.plot.api; - -public enum AggreateInternal { -NONE, MEAN, PERCENTILE95, PERCENTILE99, PERCENTILE999 -} diff --git a/pdb-ui/src/main/java/org/lucares/pdbui/domain/Aggregate.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/Aggregate.java similarity index 82% rename from pdb-ui/src/main/java/org/lucares/pdbui/domain/Aggregate.java rename to pdb-plotting/src/main/java/org/lucares/pdb/plot/api/Aggregate.java index af66e08..a2fcbfa 100644 --- a/pdb-ui/src/main/java/org/lucares/pdbui/domain/Aggregate.java +++ b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/Aggregate.java @@ -1,11 +1,9 @@ -package org.lucares.pdbui.domain; +package org.lucares.pdb.plot.api; /** * Note: The order in this enum defines the order in which the aggregates are drawn. */ public enum Aggregate { - NONE, - PARALLEL, SCATTER, diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregateHandler.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregateHandler.java index cbe6640..48af7d4 100644 --- a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregateHandler.java +++ b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregateHandler.java @@ -2,12 +2,14 @@ package org.lucares.pdb.plot.api; import java.nio.file.Path; import java.util.Collection; +import java.util.Optional; import org.lucares.recommind.logs.DataSeries; +import org.lucares.recommind.logs.LineStyle; public interface AggregateHandler { - - // TODO handle aggregates as normal DataSeries + + Aggregate getAggregateType(); void addGnuplotDefinitions(StringBuilder result, String separator, Collection dataSeries); @@ -18,10 +20,17 @@ public interface AggregateHandler { default void appendfln(final StringBuilder builder, final String format, final Object... args) { builder.append(String.format(format + "\n", args)); } + + default String gnuplotTitle(Optional title) { + + return title.isPresent() ? "title '"+title.get()+"'": "notitle"; + } - void addPlotsBeforeScatter(StringBuilder result, Collection dataSeries); - - void addPlotsAfterScatter(StringBuilder result, Collection dataSeries); +// void addPlotsBeforeScatter(StringBuilder result, Collection dataSeries); +// +// void addPlotsAfterScatter(StringBuilder result, Collection dataSeries); + + void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle, Optional title); CustomAggregator createCustomAggregator(Path tmpDir, PlotSettings plotSettings, long fromEpochMilli, long toEpochMilli); diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregateHandlerCollection.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregateHandlerCollection.java new file mode 100644 index 0000000..ad299ed --- /dev/null +++ b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregateHandlerCollection.java @@ -0,0 +1,64 @@ +package org.lucares.pdb.plot.api; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; + +import org.lucares.recommind.logs.DataSeries; + +public class AggregateHandlerCollection { + private static final Comparator COMPARATOR = Comparator.comparing(AggregateHandler::getAggregateType); + + private final List aggregateHandlers = new ArrayList<>(); + + public void add(AggregateHandler aggregateHandler) { + aggregateHandlers.add(aggregateHandler); + Collections.sort(aggregateHandlers, COMPARATOR); + } + + public void addGnuplotDefinitions(StringBuilder result, String datafileSeparator, Collection dataSeries) { + for (AggregateHandler handler : aggregateHandlers) { + handler.addGnuplotDefinitions(result, datafileSeparator, dataSeries); + } + } + + public AggregatorCollection createCustomAggregator(Path tmpDir, PlotSettings plotSettings, long fromEpochMilli, + long toEpochMilli) { + + final List aggregators = new ArrayList<>(); + + for (AggregateHandler handler : aggregateHandlers) { + CustomAggregator aggregator = handler.createCustomAggregator(tmpDir, plotSettings, fromEpochMilli, toEpochMilli); + if (aggregator != null) { + aggregators.add(aggregator); + } + } + + return new AggregatorCollection(aggregators); + } + + public void addPlots(StringBuilder result, Collection dataSeries) { + + boolean first = true; + for (AggregateHandler handler : aggregateHandlers) { + + for (DataSeries dataSerie : dataSeries) { + final Optional title = first ? Optional.of(dataSerie.getTitle()) : Optional.empty(); + + Optional aggregatedData = dataSerie.getAggregatedData().get(handler.getAggregateType()); + if(aggregatedData.isPresent()) { + handler.addPlot(result, aggregatedData.get(), dataSerie.getStyle(), title); + } + } + + first = false; + + } + + } + +} diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregatedDataCollection.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregatedDataCollection.java new file mode 100644 index 0000000..1fb342b --- /dev/null +++ b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregatedDataCollection.java @@ -0,0 +1,22 @@ +package org.lucares.pdb.plot.api; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Optional; + +public class AggregatedDataCollection implements Iterable{ + private final LinkedHashMap aggregatedDatas = new LinkedHashMap<>(); + + public void put(Aggregate aggregate, AggregatedData aggregatedData) { + aggregatedDatas.put(aggregate, aggregatedData); + } + + @Override + public Iterator iterator() { + return aggregatedDatas.values().iterator(); + } + + public Optional get(Aggregate aggregateType) { + return Optional.ofNullable(aggregatedDatas.get(aggregateType)); + } +} diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregatorCollection.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregatorCollection.java new file mode 100644 index 0000000..cc3b816 --- /dev/null +++ b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/AggregatorCollection.java @@ -0,0 +1,29 @@ +package org.lucares.pdb.plot.api; + +import java.io.IOException; +import java.util.List; + +public class AggregatorCollection { + private final List aggregators; + + public AggregatorCollection(List aggregators) { + this.aggregators = aggregators; + } + + public void addValue(boolean valueIsInYRange, long epochMilli, long value) { + for (CustomAggregator aggregator : aggregators) { + aggregator.addValue(valueIsInYRange, epochMilli, value); + } + } + + public AggregatedDataCollection getAggregatedData() throws IOException { + + AggregatedDataCollection result = new AggregatedDataCollection(); + + for (CustomAggregator aggregator : aggregators) { + result.put(aggregator.getType(), aggregator.getAggregatedData()); + } + + return result; + } +} diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/CumulativeDistributionCustomAggregator.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/CumulativeDistributionCustomAggregator.java index 46fc8d4..6091f83 100644 --- a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/CumulativeDistributionCustomAggregator.java +++ b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/CumulativeDistributionCustomAggregator.java @@ -120,4 +120,9 @@ public class CumulativeDistributionCustomAggregator implements CustomAggregator return new AggregatedData(title, dataFile); } + @Override + public Aggregate getType() { + return Aggregate.CUM_DISTRIBUTION; + } + } diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/CumulativeDistributionHandler.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/CumulativeDistributionHandler.java index 965cad5..e88a511 100644 --- a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/CumulativeDistributionHandler.java +++ b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/CumulativeDistributionHandler.java @@ -2,49 +2,44 @@ package org.lucares.pdb.plot.api; import java.nio.file.Path; import java.util.Collection; +import java.util.Optional; import org.lucares.recommind.logs.DataSeries; import org.lucares.recommind.logs.LineStyle; public class CumulativeDistributionHandler implements AggregateHandler { - @Override - public CustomAggregator createCustomAggregator(final Path tmpDir, PlotSettings plotSettings, final long fromEpochMilli, - final long toEpochMilli) { - return new CumulativeDistributionCustomAggregator(tmpDir); - } + @Override + public CustomAggregator createCustomAggregator(final Path tmpDir, PlotSettings plotSettings, + final long fromEpochMilli, final long toEpochMilli) { + return new CumulativeDistributionCustomAggregator(tmpDir); + } - public CumulativeDistributionHandler() { - } + public CumulativeDistributionHandler() { + } - @Override - public void addGnuplotDefinitions(final StringBuilder result, final String separator, - final Collection dataSeries) { + @Override + public void addGnuplotDefinitions(final StringBuilder result, final String separator, + final Collection dataSeries) { - appendln(result, "set x2label \"Cumulative Distribution\""); - appendln(result, "set format x2 \"%.0f%%\""); - appendln(result, "set x2tics 5"); - appendln(result, "set x2range [\"0\":\"100\"]"); - } + appendln(result, "set x2label \"Cumulative Distribution\""); + appendln(result, "set format x2 \"%.0f%%\""); + appendln(result, "set x2tics 5"); + appendln(result, "set x2range [\"0\":\"100\"]"); + } - @Override - public void addPlotsBeforeScatter(final StringBuilder result, final Collection dataSeries) { - // nothing to do: the percentile line should be drawn on the scatter plots and - // must therefore be rendered after the scatter - } + @Override + public void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle, Optional title) { + appendfln(result, "'%s' using 1:2 %s with lines axes x2y1 lw 2 %s, \\", // + aggregatedData.getDataFile().getAbsolutePath(), // + gnuplotTitle(title),// + lineStyle.darker()// + ); + } - @Override - public void addPlotsAfterScatter(final StringBuilder result, final Collection dataSeries) { - for (final DataSeries dataSerie : dataSeries) { - final AggregatedData aggregatedData = dataSerie.getAggregatedData(); - if (aggregatedData != null) { - final LineStyle lineStyle = dataSerie.getStyle(); - appendfln(result, "'%s' using 1:2 notitle with lines axes x2y1 lw 2 %s, \\", // - aggregatedData.getDataFile().getAbsolutePath(), // - lineStyle.darker()// - ); - } - } - } + @Override + public Aggregate getAggregateType() { + return Aggregate.CUM_DISTRIBUTION; + } } diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/CustomAggregator.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/CustomAggregator.java index b5f30f0..c9e56b2 100644 --- a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/CustomAggregator.java +++ b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/CustomAggregator.java @@ -7,4 +7,6 @@ public interface CustomAggregator { void addValue(boolean valueIsInYRange, long epochMilli, long value); AggregatedData getAggregatedData() throws IOException; + + Aggregate getType(); } diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/NullAggregate.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/NullAggregate.java deleted file mode 100644 index 0b30349..0000000 --- a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/NullAggregate.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.lucares.pdb.plot.api; - -import java.nio.file.Path; -import java.util.Collection; - -import org.lucares.recommind.logs.DataSeries; - -public class NullAggregate implements AggregateHandler { - - @Override - public void addGnuplotDefinitions(final StringBuilder result, final String separator, - final Collection dataSeries) { - // nothing to do; this is a Null-Object - } - - @Override - public void addPlotsBeforeScatter(final StringBuilder result, final Collection dataSeries) { - // nothing to do; this is a Null-Object - } - - @Override - public void addPlotsAfterScatter(final StringBuilder result, final Collection dataSeries) { - // nothing to do; this is a Null-Object - } - - @Override - public CustomAggregator createCustomAggregator(final Path tmpDir, PlotSettings plotSettings, final long fromEpochMilli, - final long toEpochMilli) { - return new NullCustomAggregator(); - } - -} diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/NullCustomAggregator.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/NullCustomAggregator.java deleted file mode 100644 index 0ca5d0a..0000000 --- a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/NullCustomAggregator.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.lucares.pdb.plot.api; - -public class NullCustomAggregator implements CustomAggregator { - - @Override - public void addValue(boolean valueIsInYRange,final long epochMilli, final long value) { - // nothing to do; this is a null-object - - } - - @Override - public AggregatedData getAggregatedData() { - return null; - } - -} diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ParallelRequestsAggregate.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ParallelRequestsAggregate.java index 4a04ad3..c1f006f 100644 --- a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ParallelRequestsAggregate.java +++ b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ParallelRequestsAggregate.java @@ -2,45 +2,43 @@ package org.lucares.pdb.plot.api; import java.nio.file.Path; import java.util.Collection; +import java.util.Optional; import java.util.concurrent.TimeUnit; import org.lucares.recommind.logs.DataSeries; +import org.lucares.recommind.logs.LineStyle; public class ParallelRequestsAggregate implements AggregateHandler { - @Override - public void addGnuplotDefinitions(final StringBuilder result, final String separator, - final Collection dataSeries) { - appendln(result, "set y2label \"Parallel Requests\""); - appendln(result, "set y2tics"); - } + @Override + public void addGnuplotDefinitions(final StringBuilder result, final String separator, + final Collection dataSeries) { + appendln(result, "set y2label \"Parallel Requests\""); + appendln(result, "set y2tics"); + } - @Override - public void addPlotsBeforeScatter(final StringBuilder result, final Collection dataSeries) { - for (final DataSeries dataSerie : dataSeries) { - final AggregatedData aggregatedData = dataSerie.getAggregatedData(); - if (aggregatedData != null) { - appendfln(result, "'%s' using 1:2 notitle with filledcurve axes x1y2 lw 1 %s, \\", // - aggregatedData.getDataFile().getAbsolutePath(), // - dataSerie.getStyle().brighter().asGnuplotLineStyle()// - ); - } - } - } + @Override + public void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle, + Optional title) { + appendfln(result, "'%s' using 1:2 %s with filledcurve axes x1y2 lw 1 %s, \\", // + aggregatedData.getDataFile().getAbsolutePath(), // + gnuplotTitle(title), // + lineStyle.brighter().asGnuplotLineStyle()// + ); + } - @Override - public void addPlotsAfterScatter(final StringBuilder result, final Collection dataSeries) { - // nothing to do: the parallel line plots shall be drawn below the scatter plot, - // so that you can see both. Therefore it must be drawn first. - } + @Override + public CustomAggregator createCustomAggregator(final Path tmpDir, PlotSettings plotSettings, + final long fromEpochMilli, final long toEpochMilli) { + if ((toEpochMilli - fromEpochMilli) <= TimeUnit.HOURS.toMillis(50)) { + return new ParallelRequestsAggregator(tmpDir, fromEpochMilli, toEpochMilli); + } else { + return null; + } + } - @Override - public CustomAggregator createCustomAggregator(final Path tmpDir, PlotSettings plotSettings, final long fromEpochMilli, - final long toEpochMilli) { - if ((toEpochMilli - fromEpochMilli) <= TimeUnit.HOURS.toMillis(5)) { - return new ParallelRequestsAggregator(tmpDir, fromEpochMilli, toEpochMilli); - } else { - return new NullCustomAggregator(); - } - } + @Override + public Aggregate getAggregateType() { + return Aggregate.PARALLEL; + } } diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ParallelRequestsAggregator.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ParallelRequestsAggregator.java index 15f0922..e8cb078 100644 --- a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ParallelRequestsAggregator.java +++ b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ParallelRequestsAggregator.java @@ -93,4 +93,9 @@ public class ParallelRequestsAggregator implements CustomAggregator { builder.append(NEWLINE); } + @Override + public Aggregate getType() { + return Aggregate.PARALLEL; + } + } diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/PlotSettings.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/PlotSettings.java index 3a39804..ef5620a 100644 --- a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/PlotSettings.java +++ b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/PlotSettings.java @@ -34,7 +34,7 @@ public class PlotSettings { private AxisScale yAxisScale; - private AggregateHandler aggregate; + private AggregateHandlerCollection aggregates; private int yRangeMin; private int yRangeMax; @@ -141,17 +141,17 @@ public class PlotSettings { return "PlotSettings [query=" + query + ", height=" + height + ", width=" + width + ", thumbnailMaxWidth=" + thumbnailMaxWidth + ", thumbnailMaxHeight=" + thumbnailMaxHeight + ", groupBy=" + groupBy + ", limitBy=" + limitBy + ", limit=" + limit + ", dateRangeAsString=" + dateRangeAsString - + ", yAxisScale=" + yAxisScale + ", aggregate=" + aggregate + ", yRangeMin=" + yRangeMin + + ", yAxisScale=" + yAxisScale + ", aggregates=" + aggregates + ", yRangeMin=" + yRangeMin + ", yRangeMax=" + yRangeMax + ", yRangeUnit=" + yRangeUnit + ", keyOutside=" + keyOutside + ", generateThumbnail=" + generateThumbnail + "]"; } - public void setAggregate(final AggregateHandler aggregate) { - this.aggregate = aggregate; + public void setAggregates(final AggregateHandlerCollection aggregates) { + this.aggregates = aggregates; } - public AggregateHandler getAggregate() { - return aggregate; + public AggregateHandlerCollection getAggregates() { + return aggregates; } public void setKeyOutside(final boolean keyOutside) { diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ScatterAggregateHandler.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ScatterAggregateHandler.java index 80658ac..33ad4e5 100644 --- a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ScatterAggregateHandler.java +++ b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ScatterAggregateHandler.java @@ -2,9 +2,11 @@ package org.lucares.pdb.plot.api; import java.nio.file.Path; import java.util.Collection; +import java.util.Optional; import org.lucares.recommind.logs.DataSeries; import org.lucares.recommind.logs.GnuplotLineType; +import org.lucares.recommind.logs.LineStyle; public class ScatterAggregateHandler implements AggregateHandler { @@ -13,29 +15,16 @@ public class ScatterAggregateHandler implements AggregateHandler { // TODO Auto-generated method stub } - + @Override - public void addPlotsBeforeScatter(StringBuilder result, Collection dataSeries) { - - for (final DataSeries dataSerie : dataSeries) { - final AggregatedData aggregatedData = dataSerie.getAggregatedData(); - if (aggregatedData != null) { - - appendfln(result, "'%s' using 1:2 title '%s' with %s %s, \\", // - aggregatedData.getDataFile(), // - dataSerie.getTitle(), // - GnuplotLineType.Points, - dataSerie.getStyle()// - ); - } - } - - } - - @Override - public void addPlotsAfterScatter(StringBuilder result, Collection dataSeries) { - // TODO Auto-generated method stub - + public void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle, Optional title) { + + appendfln(result, "'%s' using 1:2 %s with %s %s, \\", // + aggregatedData.getDataFile(), // + gnuplotTitle(title), // + GnuplotLineType.Points, // + lineStyle// + ); } @Override @@ -44,4 +33,9 @@ public class ScatterAggregateHandler implements AggregateHandler { return new ScatterAggregator(tmpDir, plotSettings, fromEpochMilli, toEpochMilli); } + + @Override + public Aggregate getAggregateType() { + return Aggregate.SCATTER; + } } diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ScatterAggregator.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ScatterAggregator.java index 8aedc95..2016a9f 100644 --- a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ScatterAggregator.java +++ b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/ScatterAggregator.java @@ -91,4 +91,9 @@ public class ScatterAggregator implements CustomAggregator { return new AggregatedData("scatter", dataFile); } + + @Override + public Aggregate getType() { + return Aggregate.SCATTER; + } } diff --git a/pdb-plotting/src/main/java/org/lucares/recommind/logs/CsvSummary.java b/pdb-plotting/src/main/java/org/lucares/recommind/logs/CsvSummary.java index 82d5cb7..3e6d1cb 100644 --- a/pdb-plotting/src/main/java/org/lucares/recommind/logs/CsvSummary.java +++ b/pdb-plotting/src/main/java/org/lucares/recommind/logs/CsvSummary.java @@ -1,16 +1,16 @@ package org.lucares.recommind.logs; -import org.lucares.pdb.plot.api.AggregatedData; +import org.lucares.pdb.plot.api.AggregatedDataCollection; class CsvSummary { private final int values; private final long maxValue; - private final AggregatedData aggregatedData; + private final AggregatedDataCollection aggregatedData; private final double statsAverage; private final int plottedValues; public CsvSummary(final int values, final int plottedValues, final long maxValue, - final double statsAverage, final AggregatedData aggregatedData) { + final double statsAverage, final AggregatedDataCollection aggregatedData) { super(); this.values = values; this.plottedValues = plottedValues; @@ -48,7 +48,7 @@ class CsvSummary { return statsAverage; } - public AggregatedData getAggregatedData() { + public AggregatedDataCollection getAggregatedData() { return aggregatedData; } } diff --git a/pdb-plotting/src/main/java/org/lucares/recommind/logs/DataSeries.java b/pdb-plotting/src/main/java/org/lucares/recommind/logs/DataSeries.java index 6b8c6d8..dcc0944 100644 --- a/pdb-plotting/src/main/java/org/lucares/recommind/logs/DataSeries.java +++ b/pdb-plotting/src/main/java/org/lucares/recommind/logs/DataSeries.java @@ -6,7 +6,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.lucares.pdb.plot.api.AggregatedData; +import org.lucares.pdb.plot.api.AggregatedDataCollection; import org.lucares.pdb.plot.api.Limit; public interface DataSeries { @@ -41,7 +41,7 @@ public interface DataSeries { public LineStyle getStyle(); - public AggregatedData getAggregatedData(); + public AggregatedDataCollection getAggregatedData(); public static Map toMap(final List dataSeries) { final Map result = new LinkedHashMap<>(); diff --git a/pdb-plotting/src/main/java/org/lucares/recommind/logs/FileBackedDataSeries.java b/pdb-plotting/src/main/java/org/lucares/recommind/logs/FileBackedDataSeries.java index e40dbdd..daf86f5 100644 --- a/pdb-plotting/src/main/java/org/lucares/recommind/logs/FileBackedDataSeries.java +++ b/pdb-plotting/src/main/java/org/lucares/recommind/logs/FileBackedDataSeries.java @@ -1,6 +1,6 @@ package org.lucares.recommind.logs; -import org.lucares.pdb.plot.api.AggregatedData; +import org.lucares.pdb.plot.api.AggregatedDataCollection; public class FileBackedDataSeries implements DataSeries { @@ -66,7 +66,7 @@ public class FileBackedDataSeries implements DataSeries { } @Override - public AggregatedData getAggregatedData() { + public AggregatedDataCollection getAggregatedData() { return csvSummary.getAggregatedData(); } } diff --git a/pdb-plotting/src/main/java/org/lucares/recommind/logs/GnuplotFileGenerator.java b/pdb-plotting/src/main/java/org/lucares/recommind/logs/GnuplotFileGenerator.java index c841a61..bd1589d 100644 --- a/pdb-plotting/src/main/java/org/lucares/recommind/logs/GnuplotFileGenerator.java +++ b/pdb-plotting/src/main/java/org/lucares/recommind/logs/GnuplotFileGenerator.java @@ -27,7 +27,7 @@ public class GnuplotFileGenerator { appendfln(result, "set datafile separator \"%s\"", settings.getDatafileSeparator()); - settings.getAggregate().addGnuplotDefinitions(result, settings.getDatafileSeparator(), dataSeries); + settings.getAggregates().addGnuplotDefinitions(result, settings.getDatafileSeparator(), dataSeries); appendfln(result, "set timefmt '%s'", settings.getTimefmt()); @@ -103,10 +103,8 @@ public class GnuplotFileGenerator { appendf(result, "plot "); - settings.getAggregate().addPlotsBeforeScatter(result, dataSeries); + settings.getAggregates().addPlots(result, dataSeries); - settings.getAggregate().addPlotsAfterScatter(result, dataSeries); - return result.toString(); } diff --git a/pdb-plotting/src/main/java/org/lucares/recommind/logs/GnuplotSettings.java b/pdb-plotting/src/main/java/org/lucares/recommind/logs/GnuplotSettings.java index 0fb090e..f4465a9 100644 --- a/pdb-plotting/src/main/java/org/lucares/recommind/logs/GnuplotSettings.java +++ b/pdb-plotting/src/main/java/org/lucares/recommind/logs/GnuplotSettings.java @@ -2,7 +2,7 @@ package org.lucares.recommind.logs; import java.nio.file.Path; -import org.lucares.pdb.plot.api.AggregateHandler; +import org.lucares.pdb.plot.api.AggregateHandlerCollection; import org.lucares.pdb.plot.api.AxisScale; public class GnuplotSettings { @@ -26,7 +26,7 @@ public class GnuplotSettings { private final Path output; private AxisScale yAxisScale; - private AggregateHandler aggregate; + private AggregateHandlerCollection aggregates; private boolean keyOutside = false; private XAxisSettings xAxisSettings = new XAxisSettings(); @@ -98,12 +98,12 @@ public class GnuplotSettings { return yAxisScale; } - public void setAggregate(final AggregateHandler aggregate) { - this.aggregate = aggregate; + public void setAggregates(final AggregateHandlerCollection aggregates) { + this.aggregates = aggregates; } - public AggregateHandler getAggregate() { - return aggregate; + public AggregateHandlerCollection getAggregates() { + return aggregates; } public void setKeyOutside(final boolean keyOutside) { diff --git a/pdb-plotting/src/main/java/org/lucares/recommind/logs/Plotter.java b/pdb-plotting/src/main/java/org/lucares/recommind/logs/Plotter.java index 243e701..4d7735e 100644 --- a/pdb-plotting/src/main/java/org/lucares/recommind/logs/Plotter.java +++ b/pdb-plotting/src/main/java/org/lucares/recommind/logs/Plotter.java @@ -22,7 +22,7 @@ import org.lucares.pdb.api.GroupResult; import org.lucares.pdb.api.Query; import org.lucares.pdb.api.Result; import org.lucares.pdb.api.Tags; -import org.lucares.pdb.plot.api.CustomAggregator; +import org.lucares.pdb.plot.api.AggregatorCollection; import org.lucares.pdb.plot.api.Limit; import org.lucares.pdb.plot.api.PlotSettings; import org.lucares.pdb.plot.api.TimeRangeUnitInternal; @@ -115,7 +115,7 @@ public class Plotter { defineXAxis(gnuplotSettings, plotSettings.dateRange()); gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale()); - gnuplotSettings.setAggregate(plotSettings.getAggregate()); + gnuplotSettings.setAggregates(plotSettings.getAggregates()); defineYRange(gnuplotSettings, plotSettings.getYRangeMin(), plotSettings.getYRangeMax(), plotSettings.getYRangeUnit()); gnuplotSettings.setKeyOutside(plotSettings.isKeyOutside()); @@ -132,7 +132,7 @@ public class Plotter { defineXAxis(gnuplotSettings, plotSettings.dateRange()); gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale()); - gnuplotSettings.setAggregate(plotSettings.getAggregate()); + gnuplotSettings.setAggregates(plotSettings.getAggregates()); defineYRange(gnuplotSettings, plotSettings.getYRangeMin(), plotSettings.getYRangeMax(), plotSettings.getYRangeUnit()); gnuplotSettings.setKeyOutside(false); @@ -205,7 +205,7 @@ public class Plotter { final long maxValue = plotSettings.getYRangeUnit() == TimeRangeUnitInternal.AUTOMATIC ? Long.MAX_VALUE : plotSettings.getYRangeUnit().toMilliSeconds(plotSettings.getYRangeMax()); - final CustomAggregator aggregator = plotSettings.getAggregate().createCustomAggregator(tmpDir, plotSettings, fromEpochMilli, + final AggregatorCollection aggregator = plotSettings.getAggregates().createCustomAggregator(tmpDir, plotSettings, fromEpochMilli, toEpochMilli); int count = 0; // number of values in the x-axis range (used to compute stats) @@ -228,8 +228,6 @@ public class Plotter { final long value = entry.get(i + 1); - - // compute stats count++; statsMaxValue = Math.max(statsMaxValue, value); @@ -293,7 +291,5 @@ public class Plotter { result.append(")"); return result.toString(); - } - } diff --git a/pdb-ui/src/main/java/org/lucares/pdbui/PdbController.java b/pdb-ui/src/main/java/org/lucares/pdbui/PdbController.java index eedbee4..8bf20a9 100644 --- a/pdb-ui/src/main/java/org/lucares/pdbui/PdbController.java +++ b/pdb-ui/src/main/java/org/lucares/pdbui/PdbController.java @@ -6,6 +6,7 @@ import java.io.OutputStream; import java.text.Collator; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -20,10 +21,10 @@ 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.Aggregate; import org.lucares.pdb.plot.api.AxisScale; import org.lucares.pdb.plot.api.Limit; import org.lucares.pdb.plot.api.PlotSettings; -import org.lucares.pdbui.domain.Aggregate; import org.lucares.pdbui.domain.AutocompleteProposal; import org.lucares.pdbui.domain.AutocompleteProposalByValue; import org.lucares.pdbui.domain.AutocompleteResponse; @@ -158,7 +159,7 @@ public class PdbController implements HardcodedValues, PropertyKeys { @RequestParam(name = "limitBy.selected", defaultValue = "NO_LIMIT") final Limit limitBy, @RequestParam(name = "dateRange") final String dateRange, @RequestParam(name = "axisScale", defaultValue = "LINEAR") final AxisScale axisScale, - @RequestParam(name = "aggregate", defaultValue = "NONE") final Aggregate aggregate, + @RequestParam(name = "aggregates") final EnumSetaggregate, @RequestParam(name = "keyOutside", defaultValue = "false") final boolean keyOutside, @RequestParam(name = "width", defaultValue = "1920") final int hidth, @RequestParam(name = "height", defaultValue = "1080") final int height) { @@ -181,7 +182,7 @@ public class PdbController implements HardcodedValues, PropertyKeys { plotSettings.setLimitBy(limitBy); plotSettings.setDateRange(dateRange); plotSettings.setYAxisScale(axisScale); - plotSettings.setAggregate(PlotSettingsTransformer.toAggregateInternal(aggregate)); + plotSettings.setAggregates(PlotSettingsTransformer.toAggregateInternal(aggregate)); plotSettings.setKeyOutside(keyOutside); plotSettings.setGenerateThumbnail(false); diff --git a/pdb-ui/src/main/java/org/lucares/pdbui/PlotSettingsTransformer.java b/pdb-ui/src/main/java/org/lucares/pdbui/PlotSettingsTransformer.java index 6b44740..3706123 100644 --- a/pdb-ui/src/main/java/org/lucares/pdbui/PlotSettingsTransformer.java +++ b/pdb-ui/src/main/java/org/lucares/pdbui/PlotSettingsTransformer.java @@ -1,70 +1,78 @@ package org.lucares.pdbui; -import org.lucares.pdb.plot.api.AggregateHandler; -import org.lucares.pdb.plot.api.NullAggregate; -import org.lucares.pdb.plot.api.ParallelRequestsAggregate; +import org.lucares.pdb.plot.api.Aggregate; +import org.lucares.pdb.plot.api.AggregateHandlerCollection; import org.lucares.pdb.plot.api.CumulativeDistributionHandler; +import org.lucares.pdb.plot.api.ParallelRequestsAggregate; import org.lucares.pdb.plot.api.PlotSettings; import org.lucares.pdb.plot.api.ScatterAggregateHandler; import org.lucares.pdb.plot.api.TimeRangeUnitInternal; -import org.lucares.pdbui.domain.Aggregate; import org.lucares.pdbui.domain.PlotRequest; import org.lucares.pdbui.domain.TimeRangeUnit; class PlotSettingsTransformer { - static PlotSettings toSettings(final PlotRequest request) { + static PlotSettings toSettings(final PlotRequest request) { - final PlotSettings result = new PlotSettings(); + final PlotSettings result = new PlotSettings(); - result.setQuery(request.getQuery()); - result.setGroupBy(request.getGroupBy()); - result.setHeight(request.getHeight()); - result.setWidth(request.getWidth()); - result.setLimit(request.getLimit()); - result.setLimitBy(request.getLimitBy()); - result.setDateRange(request.getDateRange()); - result.setYAxisScale(request.getAxisScale()); - result.setAggregate(toAggregateInternal(request.getAggregate())); - result.setKeyOutside(request.isKeyOutside()); - result.setThumbnailMaxWidth(request.getThumbnailMaxWidth()); - result.setThumbnailMaxHeight(request.getThumbnailMaxHeight()); - result.setGenerateThumbnail(request.isGenerateThumbnail()); - result.setYRangeMin(request.getyRangeMin()); - result.setYRangeMax(request.getyRangeMax()); - result.setYRangeUnit(toTimeRangeUnitInternal(request.getyRangeUnit())); + result.setQuery(request.getQuery()); + result.setGroupBy(request.getGroupBy()); + result.setHeight(request.getHeight()); + result.setWidth(request.getWidth()); + result.setLimit(request.getLimit()); + result.setLimitBy(request.getLimitBy()); + result.setDateRange(request.getDateRange()); + result.setYAxisScale(request.getAxisScale()); + result.setAggregates(toAggregateInternal(request.getAggregates())); + result.setKeyOutside(request.isKeyOutside()); + result.setThumbnailMaxWidth(request.getThumbnailMaxWidth()); + result.setThumbnailMaxHeight(request.getThumbnailMaxHeight()); + result.setGenerateThumbnail(request.isGenerateThumbnail()); + result.setYRangeMin(request.getyRangeMin()); + result.setYRangeMax(request.getyRangeMax()); + result.setYRangeUnit(toTimeRangeUnitInternal(request.getyRangeUnit())); - return result; - } + return result; + } - private static TimeRangeUnitInternal toTimeRangeUnitInternal(final TimeRangeUnit yRangeUnit) { - switch (yRangeUnit) { - case AUTOMATIC: - return TimeRangeUnitInternal.AUTOMATIC; - case MILLISECONDS: - return TimeRangeUnitInternal.MILLISECONDS; - case SECONDS: - return TimeRangeUnitInternal.SECONDS; - case MINUTES: - return TimeRangeUnitInternal.MINUTES; - case HOURS: - return TimeRangeUnitInternal.HOURS; - case DAYS: - return TimeRangeUnitInternal.DAYS; - } - throw new IllegalStateException("unhandled enum value: " + yRangeUnit); - } + private static TimeRangeUnitInternal toTimeRangeUnitInternal(final TimeRangeUnit yRangeUnit) { + switch (yRangeUnit) { + case AUTOMATIC: + return TimeRangeUnitInternal.AUTOMATIC; + case MILLISECONDS: + return TimeRangeUnitInternal.MILLISECONDS; + case SECONDS: + return TimeRangeUnitInternal.SECONDS; + case MINUTES: + return TimeRangeUnitInternal.MINUTES; + case HOURS: + return TimeRangeUnitInternal.HOURS; + case DAYS: + return TimeRangeUnitInternal.DAYS; + } + throw new IllegalStateException("unhandled enum value: " + yRangeUnit); + } - static AggregateHandler toAggregateInternal(final Aggregate aggregate) { - switch (aggregate) { - case NONE: - return new NullAggregate(); - case CUM_DISTRIBUTION: - return new CumulativeDistributionHandler(); - case PARALLEL: - return new ParallelRequestsAggregate(); - case SCATTER: - return new ScatterAggregateHandler(); - } - throw new IllegalStateException("unhandled enum: " + aggregate); - } + static AggregateHandlerCollection toAggregateInternal(final Iterable aggregates) { + final AggregateHandlerCollection aggregateHandlerCollection = new AggregateHandlerCollection(); + + for (Aggregate aggregate : aggregates) { + + switch (aggregate) { + case CUM_DISTRIBUTION: + aggregateHandlerCollection.add(new CumulativeDistributionHandler()); + break; + case PARALLEL: + aggregateHandlerCollection.add(new ParallelRequestsAggregate()); + break; + case SCATTER: + aggregateHandlerCollection.add(new ScatterAggregateHandler()); + break; + default: + throw new IllegalStateException("unhandled enum: " + aggregate); + } + } + + return aggregateHandlerCollection; + } } diff --git a/pdb-ui/src/main/java/org/lucares/pdbui/domain/PlotRequest.java b/pdb-ui/src/main/java/org/lucares/pdbui/domain/PlotRequest.java index 3c06b57..a715d60 100644 --- a/pdb-ui/src/main/java/org/lucares/pdbui/domain/PlotRequest.java +++ b/pdb-ui/src/main/java/org/lucares/pdbui/domain/PlotRequest.java @@ -1,7 +1,9 @@ package org.lucares.pdbui.domain; +import java.util.ArrayList; import java.util.List; +import org.lucares.pdb.plot.api.Aggregate; import org.lucares.pdb.plot.api.AxisScale; import org.lucares.pdb.plot.api.Limit; @@ -26,7 +28,7 @@ public class PlotRequest { private String dateRange; - private Aggregate aggregate = Aggregate.NONE; + private List aggregates = new ArrayList<>(); private int yRangeMin; private int yRangeMax; @@ -121,12 +123,12 @@ public class PlotRequest { this.yAxis = yAxis; } - public void setAggregate(final Aggregate aggregate) { - this.aggregate = aggregate; + public void setAggregate(final List aggregates) { + this.aggregates = aggregates; } - public Aggregate getAggregate() { - return aggregate; + public List getAggregates() { + return aggregates; } public void setKeyOutside(final boolean keyOutside) { diff --git a/pdb-ui/src/main/resources/resources/js/ui.js b/pdb-ui/src/main/resources/resources/js/ui.js index 98f7269..3f5259d 100644 --- a/pdb-ui/src/main/resources/resources/js/ui.js +++ b/pdb-ui/src/main/resources/resources/js/ui.js @@ -780,7 +780,7 @@ Vue.component('search-bar', {
-