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 85d1cf2..096a9d3 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 @@ -40,8 +40,6 @@ public class PlotSettings { private boolean keyOutside; - private PlotType plotType; - private boolean generateThumbnail; public String getQuery() { @@ -185,8 +183,7 @@ public class PlotSettings { return "PlotSettings [query=" + query + ", height=" + height + ", width=" + width + ", thumbnailMaxWidth=" + thumbnailMaxWidth + ", thumbnailMaxHeight=" + thumbnailMaxHeight + ", groupBy=" + groupBy + ", limitBy=" + limitBy + ", limit=" + limit + ", dateFrom=" + dateFrom + ", dateRange=" + dateRange - + ", yAxisScale=" + yAxisScale + ", aggregate=" + aggregate + ", keyOutside=" + keyOutside - + ", plotType=" + plotType + "]"; + + ", yAxisScale=" + yAxisScale + ", aggregate=" + aggregate + ", keyOutside=" + keyOutside + "]"; } public void setAggregate(final AggregateHandler aggregate) { @@ -205,14 +202,6 @@ public class PlotSettings { return keyOutside; } - public void setPlotType(final PlotType plotType) { - this.plotType = plotType; - } - - public PlotType getPlotType() { - return plotType; - } - public void setGenerateThumbnail(final boolean generateThumbnail) { this.generateThumbnail = generateThumbnail; } diff --git a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/PlotType.java b/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/PlotType.java deleted file mode 100644 index baaa9eb..0000000 --- a/pdb-plotting/src/main/java/org/lucares/pdb/plot/api/PlotType.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.lucares.pdb.plot.api; - -public enum PlotType { - SCATTER, PERCENTILES -} diff --git a/pdb-plotting/src/main/java/org/lucares/recommind/logs/ConcretePlotter.java b/pdb-plotting/src/main/java/org/lucares/recommind/logs/ConcretePlotter.java deleted file mode 100644 index e8a682f..0000000 --- a/pdb-plotting/src/main/java/org/lucares/recommind/logs/ConcretePlotter.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.lucares.recommind.logs; - -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; -import java.util.UUID; - -import org.lucares.pdb.api.Tags; -import org.lucares.pdb.plot.api.PlotSettings; - -public interface ConcretePlotter { - - static final String DEFAULT_GROUP = ""; - - PlotResult plot(PlotSettings plotSettings) throws InternalPlottingException; - - - - static String uniqueDirectoryName() { - return OffsetDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH_mm_ss")) + "_" - + UUID.randomUUID().toString(); - } - - static String title(final Tags tags, final int values) { - - final StringBuilder result = new StringBuilder(); - - if (tags.isEmpty()) { - result.append(DEFAULT_GROUP); - } else { - tags.forEach((k, v) -> { - if (result.length() > 0) { - result.append(" / "); - } - result.append(v); - }); - } - - result.append(" ("); - result.append(String.format("%,d", values)); - result.append(")"); - - return result.toString(); - - } -} diff --git a/pdb-plotting/src/main/java/org/lucares/recommind/logs/PercentilePlot.java b/pdb-plotting/src/main/java/org/lucares/recommind/logs/PercentilePlot.java deleted file mode 100644 index cb2e0f0..0000000 --- a/pdb-plotting/src/main/java/org/lucares/recommind/logs/PercentilePlot.java +++ /dev/null @@ -1,189 +0,0 @@ -package org.lucares.recommind.logs; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Stream; - -import org.lucares.collections.IntList; -import org.lucares.pdb.api.Entry; -import org.lucares.pdb.api.GroupResult; -import org.lucares.pdb.api.Result; -import org.lucares.pdb.plot.api.Limit; -import org.lucares.pdb.plot.api.PlotSettings; -import org.lucares.performance.db.PerformanceDb; -import org.lucares.utils.file.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PercentilePlot implements ConcretePlotter { - private static final Logger LOGGER = LoggerFactory.getLogger(ScatterPlot.class); - private static final Logger METRICS_LOGGER = LoggerFactory.getLogger("org.lucares.metrics.plotter.percentile"); - private final PerformanceDb db; - private final Path tmpBaseDir; - private final Path outputDir; - - public PercentilePlot(final PerformanceDb db, final Path tmpBaseDir, final Path outputDir) { - this.db = db; - this.tmpBaseDir = tmpBaseDir; - this.outputDir = outputDir; - } - - @Override - public PlotResult plot(final PlotSettings plotSettings) throws InternalPlottingException { - - LOGGER.trace("start plot: {}", plotSettings); - - final String tmpSubDir = ConcretePlotter.uniqueDirectoryName(); - final Path tmpDir = tmpBaseDir.resolve(tmpSubDir); - try { - Files.createDirectories(tmpDir); - final List dataSeries = Collections.synchronizedList(new ArrayList<>()); - - final String query = plotSettings.getQuery(); - final List groupBy = plotSettings.getGroupBy(); - final int height = plotSettings.getHeight(); - final int width = plotSettings.getWidth(); - final OffsetDateTime dateFrom = plotSettings.dateFrom(); - final OffsetDateTime dateTo = plotSettings.dateTo(); - - final Result result = db.get(query, groupBy); - - final long start = System.nanoTime(); - final AtomicInteger idCounter = new AtomicInteger(0); - result.getGroups().stream().parallel().forEach(groupResult -> { - try { - final int id = idCounter.getAndIncrement(); - - final FileBackedDataSeries dataSerie = toCsv(id, groupResult, tmpDir, dateFrom, dateTo, - plotSettings); - - if (dataSerie.getValues() > 0) { - dataSeries.add(dataSerie); - } - } catch (final Exception e) { - throw new IllegalStateException(e); // TODO - // handle - } - }); - METRICS_LOGGER.debug("csv generation took: " + (System.nanoTime() - start) / 1_000_000.0 + "ms"); - - if (dataSeries.isEmpty()) { - throw new NoDataPointsException(); - } - - final Limit limitBy = plotSettings.getLimitBy(); - final int limit = plotSettings.getLimit(); - DataSeries.sortAndLimit(dataSeries, limitBy, limit); - DataSeries.setColors(dataSeries); - - final Path outputFile = Files.createTempFile(outputDir, "out", ".png"); - final Gnuplot gnuplot = new Gnuplot(tmpBaseDir); - final GnuplotSettings gnuplotSettings = new GnuplotSettings(outputFile); - gnuplotSettings.setHeight(height); - gnuplotSettings.setWidth(width); - defineXAxis(gnuplotSettings); - - gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale()); - gnuplotSettings.setAggregate(plotSettings.getAggregate()); - gnuplotSettings.setKeyOutside(plotSettings.isKeyOutside()); - gnuplot.plot(gnuplotSettings, dataSeries); - - return new PlotResult(outputFile, dataSeries, null); // TODO thumbail - } catch (final InterruptedException e) { - Thread.currentThread().interrupt(); - throw new IllegalStateException("Plotting was interrupted."); - } catch (final IOException e) { - throw new InternalPlottingException("Plotting failed: " + e.getMessage(), e); - } finally { - FileUtils.delete(tmpDir); - LOGGER.trace("done plot"); - } - } - - private FileBackedDataSeries toCsv(final int id, final GroupResult groupResult, final Path tmpDir, - final OffsetDateTime dateFrom, final OffsetDateTime dateTo, final PlotSettings plotSettings) - throws IOException { - - final long start = System.nanoTime(); - final Stream entries = groupResult.asStream(); - int count = 0; - final long fromEpochMilli = dateFrom.toInstant().toEpochMilli(); - final long toEpochMilli = dateTo.toInstant().toEpochMilli(); - - long ignoredValues = 0; - final char separator = ','; - final char newline = '\n'; - final IntList values = new IntList(); // TODO should be a LongList - long maxValue = 0; - - final Iterator it = entries.iterator(); - while (it.hasNext()) { - final Entry entry = it.next(); - - final long epochMilli = entry.getEpochMilli(); - if (fromEpochMilli <= epochMilli && epochMilli <= toEpochMilli) { - - final long value = entry.getValue(); - values.add((int) value); - count++; - } else { - ignoredValues++; - } - } - - values.parallelSort(); - - final File dataFile = File.createTempFile("data", ".dat", tmpDir.toFile()); - try (final Writer output = new BufferedWriter( - new OutputStreamWriter(new FileOutputStream(dataFile), StandardCharsets.US_ASCII));) { - - final StringBuilder data = new StringBuilder(); - if (values.size() > 0) { - // compute the percentiles - for (int i = 0; i < 100; i++) { - data.append(i); - data.append(separator); - data.append(values.get((int) Math.floor(values.size() / 100.0 * i))); - data.append(newline); - } - maxValue = values.get(values.size() - 1); - data.append(100); - data.append(separator); - data.append(maxValue); - data.append(newline); - } - output.write(data.toString()); - } - METRICS_LOGGER.debug("wrote {} values to csv in: {}ms (ignored {} values) grouping={}", count, - (System.nanoTime() - start) / 1_000_000.0, ignoredValues, groupResult.getGroupedBy()); - - final String title = ConcretePlotter.title(groupResult.getGroupedBy(), values.size()); - - final CsvSummary csvSummary = new CsvSummary(dataFile, values.size(), maxValue, null); - return new FileBackedDataSeries(id, title, csvSummary, GnuplotLineType.LINE); - } - - private void defineXAxis(final GnuplotSettings gnuplotSettings) { - final XAxisSettings xAxis = gnuplotSettings.getxAxisSettings(); - xAxis.setxDataTime(false); - xAxis.setFrom("0"); - xAxis.setTo("100"); - xAxis.setRotateXAxisLabel(0); - xAxis.setFormatX("%.0f"); - xAxis.setXlabel("Percentile"); - } - -} 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 ae91760..d7f00f5 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 @@ -5,7 +5,6 @@ import java.nio.file.LinkOption; import java.nio.file.Path; import org.lucares.pdb.plot.api.PlotSettings; -import org.lucares.pdb.plot.api.PlotType; import org.lucares.performance.db.PerformanceDb; public class Plotter { @@ -32,26 +31,10 @@ public class Plotter { } public PlotResult plot(final PlotSettings plotSettings) throws InternalPlottingException { - - PlotType plotType = plotSettings.getPlotType(); - final ConcretePlotter plotter; - switch (plotType) { - case SCATTER: - plotter = new ScatterPlot(db, tmpBaseDir, outputDir); - break; - case PERCENTILES: - plotter = new PercentilePlot(db, tmpBaseDir, outputDir); - break; - default: - throw new UnsupportedOperationException("plot of type " + plotType + " not supported."); - } - + + final ScatterPlot plotter = new ScatterPlot(db, tmpBaseDir, outputDir); + return plotter.plot(plotSettings); } - - - - - } diff --git a/pdb-plotting/src/main/java/org/lucares/recommind/logs/ScatterPlot.java b/pdb-plotting/src/main/java/org/lucares/recommind/logs/ScatterPlot.java index e939a6a..fb4334b 100644 --- a/pdb-plotting/src/main/java/org/lucares/recommind/logs/ScatterPlot.java +++ b/pdb-plotting/src/main/java/org/lucares/recommind/logs/ScatterPlot.java @@ -11,12 +11,14 @@ import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Collections; import java.util.Formatter; import java.util.Iterator; import java.util.List; +import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; @@ -24,6 +26,7 @@ import java.util.stream.Stream; import org.lucares.pdb.api.Entry; import org.lucares.pdb.api.GroupResult; 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.Limit; import org.lucares.pdb.plot.api.PlotSettings; @@ -32,11 +35,13 @@ import org.lucares.utils.file.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ScatterPlot implements ConcretePlotter { +public class ScatterPlot { private static final Logger LOGGER = LoggerFactory.getLogger(ScatterPlot.class); private static final Logger METRICS_LOGGER = LoggerFactory.getLogger("org.lucares.metrics.plotter.scatter"); + static final String DEFAULT_GROUP = ""; + private final PerformanceDb db; private final Path tmpBaseDir; private final Path outputDir; @@ -58,12 +63,11 @@ public class ScatterPlot implements ConcretePlotter { return outputDir; } - @Override public PlotResult plot(final PlotSettings plotSettings) throws InternalPlottingException { LOGGER.trace("start plot: {}", plotSettings); - final String tmpSubDir = ConcretePlotter.uniqueDirectoryName(); + final String tmpSubDir = uniqueDirectoryName(); final Path tmpDir = tmpBaseDir.resolve(tmpSubDir); try { Files.createDirectories(tmpDir); @@ -85,7 +89,7 @@ public class ScatterPlot implements ConcretePlotter { final CsvSummary csvSummary = toCsv(groupResult, tmpDir, dateFrom, dateTo, plotSettings); final int id = idCounter.incrementAndGet(); - final String title = ConcretePlotter.title(groupResult.getGroupedBy(), csvSummary.getValues()); + final String title = title(groupResult.getGroupedBy(), csvSummary.getValues()); final DataSeries dataSerie = new FileBackedDataSeries(id, title, csvSummary, GnuplotLineType.Points); if (dataSerie.getValues() > 0) { @@ -237,4 +241,31 @@ public class ScatterPlot implements ConcretePlotter { return new CsvSummary(dataFile, count, maxValue, aggregator.getAggregatedData()); } + static String uniqueDirectoryName() { + return OffsetDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH_mm_ss")) + "_" + + UUID.randomUUID().toString(); + } + + static String title(final Tags tags, final int values) { + + final StringBuilder result = new StringBuilder(); + + if (tags.isEmpty()) { + result.append(DEFAULT_GROUP); + } else { + tags.forEach((k, v) -> { + if (result.length() > 0) { + result.append(" / "); + } + result.append(v); + }); + } + + result.append(" ("); + result.append(String.format("%,d", values)); + 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 94a38eb..c42a9d3 100644 --- a/pdb-ui/src/main/java/org/lucares/pdbui/PdbController.java +++ b/pdb-ui/src/main/java/org/lucares/pdbui/PdbController.java @@ -19,7 +19,6 @@ import org.lucares.pdb.datastore.Proposal; import org.lucares.pdb.plot.api.AxisScale; import org.lucares.pdb.plot.api.Limit; import org.lucares.pdb.plot.api.PlotSettings; -import org.lucares.pdb.plot.api.PlotType; import org.lucares.pdbui.domain.Aggregate; import org.lucares.pdbui.domain.AutocompleteProposal; import org.lucares.pdbui.domain.AutocompleteProposalByValue; @@ -160,7 +159,6 @@ public class PdbController implements HardcodedValues, PropertyKeys { @RequestParam(name = "dateFrom", defaultValue = "") final String dateFrom, @RequestParam(name = "dateRange", defaultValue = "1 week") final String dateRange, @RequestParam(name = "axisScale", defaultValue = "LINEAR") final AxisScale axisScale, - @RequestParam(name = "plotType", defaultValue = "SCATTER") final PlotType plotType, @RequestParam(name = "aggregate", defaultValue = "NONE") final Aggregate aggregate, @RequestParam(name = "keyOutside", defaultValue = "false") final boolean keyOutside, @RequestParam(name = "width", defaultValue = "1920") final int hidth, @@ -181,7 +179,6 @@ public class PdbController implements HardcodedValues, PropertyKeys { plotSettings.setDateFrom(dateFrom); plotSettings.setDateRange(dateRange); plotSettings.setYAxisScale(axisScale); - plotSettings.setPlotType(plotType); plotSettings.setAggregate(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 da067c0..1aa5677 100644 --- a/pdb-ui/src/main/java/org/lucares/pdbui/PlotSettingsTransformer.java +++ b/pdb-ui/src/main/java/org/lucares/pdbui/PlotSettingsTransformer.java @@ -21,7 +21,6 @@ class PlotSettingsTransformer { result.setDateFrom(request.getDateFrom()); result.setDateRange(request.getDateRange()); result.setYAxisScale(request.getAxisScale()); - result.setPlotType(request.getPlotType()); result.setAggregate(toAggregateInternal(request.getAggregate())); result.setKeyOutside(request.isKeyOutside()); result.setThumbnailMaxWidth(request.getThumbnailMaxWidth()); 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 35d5037..e3e2a4d 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 @@ -4,7 +4,6 @@ import java.util.List; import org.lucares.pdb.plot.api.AxisScale; import org.lucares.pdb.plot.api.Limit; -import org.lucares.pdb.plot.api.PlotType; public class PlotRequest { private String query; @@ -29,8 +28,6 @@ public class PlotRequest { private String dateRange; - private PlotType plotType = PlotType.SCATTER; - private Aggregate aggregate = Aggregate.NONE; private boolean keyOutside; @@ -133,14 +130,6 @@ public class PlotRequest { this.yAxis = yAxis; } - public PlotType getPlotType() { - return plotType; - } - - public void setPlotType(final PlotType plotType) { - this.plotType = plotType; - } - public void setAggregate(final Aggregate aggregate) { this.aggregate = aggregate; } diff --git a/pdb-ui/src/main/resources/resources/js/ui.js b/pdb-ui/src/main/resources/resources/js/ui.js index 29d7f34..824480a 100644 --- a/pdb-ui/src/main/resources/resources/js/ui.js +++ b/pdb-ui/src/main/resources/resources/js/ui.js @@ -594,7 +594,6 @@ Vue.component('search-bar', { 'dateFrom': data.searchBar.dateFrom, 'dateRange': data.searchBar.dateRange, 'axisScale': data.searchBar.axisScale, - 'plotType': data.searchBar.plotType, 'aggregate': data.searchBar.aggregate, 'keyOutside': data.searchBar.keyOutside, }; @@ -683,15 +682,8 @@ Vue.component('search-bar', { -
- - -
-
+