put y axis definition into its own object
This commit is contained in:
@@ -1,12 +1,9 @@
|
||||
package org.lucares.pdbui;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
@@ -23,9 +20,6 @@ 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.AutocompleteProposal;
|
||||
import org.lucares.pdbui.domain.AutocompleteProposalByValue;
|
||||
@@ -48,7 +42,6 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -60,7 +53,6 @@ import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
@@ -156,65 +148,64 @@ public class PdbController implements HardcodedValues, PropertyKeys {
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/plots", //
|
||||
method = RequestMethod.GET, //
|
||||
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE //
|
||||
)
|
||||
StreamingResponseBody createPlotImage(@RequestParam(name = "query", defaultValue = "") final String query,
|
||||
@RequestParam(name = "groupBy[]", defaultValue = "") final List<String> aGroupBy,
|
||||
@RequestParam(name = "limitBy.number", defaultValue = "10") final int limit,
|
||||
@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 = "aggregates") final EnumSet<Aggregate> aggregate,
|
||||
@RequestParam(name = "keyOutside", defaultValue = "false") final boolean keyOutside,
|
||||
@RequestParam(name = "width", defaultValue = "1920") final int hidth,
|
||||
@RequestParam(name = "height", defaultValue = "1080") final int height) {
|
||||
return (final OutputStream outputStream) -> {
|
||||
|
||||
if (StringUtils.isBlank(query)) {
|
||||
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();
|
||||
plotSettings.setQuery(query);
|
||||
plotSettings.setGroupBy(aGroupBy);
|
||||
plotSettings.setHeight(height);
|
||||
plotSettings.setWidth(hidth);
|
||||
plotSettings.setLimit(limit);
|
||||
plotSettings.setLimitBy(limitBy);
|
||||
plotSettings.setDateRange(dateRange);
|
||||
plotSettings.setYAxisScale(axisScale);
|
||||
plotSettings.setAggregates(PlotSettingsTransformer.toAggregateInternal(plotSettings.getYRangeUnit(),
|
||||
plotSettings.getYAxisScale(), aggregate));
|
||||
plotSettings.setKeyOutside(keyOutside);
|
||||
plotSettings.setGenerateThumbnail(false);
|
||||
|
||||
if (plotterLock.tryLock()) {
|
||||
try {
|
||||
final PlotResult result = plotter.plot(plotSettings);
|
||||
|
||||
try (FileInputStream in = new FileInputStream(result.getImagePath().toFile())) {
|
||||
StreamUtils.copy(in, outputStream);
|
||||
}
|
||||
} catch (final NoDataPointsException e) {
|
||||
throw new NotFoundException(e);
|
||||
} catch (final InternalPlottingException e) {
|
||||
throw new InternalServerError(e);
|
||||
} finally {
|
||||
plotterLock.unlock();
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new ServiceUnavailableException("Too many parallel requests!");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* @RequestMapping(path = "/plots", // method = RequestMethod.GET, // produces =
|
||||
* MediaType.APPLICATION_OCTET_STREAM_VALUE // ) StreamingResponseBody
|
||||
* createPlotImage(@RequestParam(name = "query", defaultValue = "") final String
|
||||
* query,
|
||||
*
|
||||
* @RequestParam(name = "groupBy[]", defaultValue = "") final List<String>
|
||||
* aGroupBy,
|
||||
*
|
||||
* @RequestParam(name = "limitBy.number", defaultValue = "10") final int limit,
|
||||
*
|
||||
* @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 = "aggregates") final EnumSet<Aggregate> aggregate,
|
||||
*
|
||||
* @RequestParam(name = "keyOutside", defaultValue = "false") final boolean
|
||||
* keyOutside,
|
||||
*
|
||||
* @RequestParam(name = "width", defaultValue = "1920") final int hidth,
|
||||
*
|
||||
* @RequestParam(name = "height", defaultValue = "1080") final int height) {
|
||||
* return (final OutputStream outputStream) -> {
|
||||
*
|
||||
* if (StringUtils.isBlank(query)) { 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();
|
||||
* plotSettings.setQuery(query); plotSettings.setGroupBy(aGroupBy);
|
||||
* plotSettings.setHeight(height); plotSettings.setWidth(hidth);
|
||||
* plotSettings.setLimit(limit); plotSettings.setLimitBy(limitBy);
|
||||
* plotSettings.setDateRange(dateRange); plotSettings.setY1(y1);
|
||||
* plotSettings.setYAxisScale(axisScale);
|
||||
* plotSettings.setAggregates(PlotSettingsTransformer.toAggregateInternal(
|
||||
* plotSettings.getYRangeUnit(), plotSettings.getYAxisScale(), aggregate));
|
||||
* plotSettings.setKeyOutside(keyOutside);
|
||||
* plotSettings.setGenerateThumbnail(false);
|
||||
*
|
||||
* if (plotterLock.tryLock()) { try { final PlotResult result =
|
||||
* plotter.plot(plotSettings);
|
||||
*
|
||||
* try (FileInputStream in = new
|
||||
* FileInputStream(result.getImagePath().toFile())) { StreamUtils.copy(in,
|
||||
* outputStream); } } catch (final NoDataPointsException e) { throw new
|
||||
* NotFoundException(e); } catch (final InternalPlottingException e) { throw new
|
||||
* InternalServerError(e); } finally { plotterLock.unlock(); }
|
||||
*
|
||||
* } else { throw new
|
||||
* ServiceUnavailableException("Too many parallel requests!"); } }; }
|
||||
*/
|
||||
@RequestMapping(path = "/autocomplete", //
|
||||
method = RequestMethod.GET, //
|
||||
produces = MediaType.APPLICATION_JSON_VALUE //
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.lucares.pdbui;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.lucares.pdb.plot.api.Aggregate;
|
||||
import org.lucares.pdb.plot.api.AggregateHandlerCollection;
|
||||
import org.lucares.pdb.plot.api.AxisScale;
|
||||
@@ -10,6 +12,7 @@ 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.TimeRangeUnit;
|
||||
import org.lucares.pdb.plot.api.YAxisDefinition;
|
||||
import org.lucares.pdbui.domain.PlotRequest;
|
||||
|
||||
class PlotSettingsTransformer {
|
||||
@@ -24,40 +27,20 @@ class PlotSettingsTransformer {
|
||||
result.setLimit(request.getLimit());
|
||||
result.setLimitBy(request.getLimitBy());
|
||||
result.setDateRange(request.getDateRange());
|
||||
result.setYAxisScale(request.getY1().getAxisScale());
|
||||
|
||||
result.setKeyOutside(request.isKeyOutside());
|
||||
result.setThumbnailMaxWidth(request.getThumbnailMaxWidth());
|
||||
result.setThumbnailMaxHeight(request.getThumbnailMaxHeight());
|
||||
result.setGenerateThumbnail(request.isGenerateThumbnail());
|
||||
result.setYRangeMin(request.getY1().getyRangeMin());
|
||||
result.setYRangeMax(request.getY1().getyRangeMax());
|
||||
result.setYRangeUnit(toTimeRangeUnitInternal(request.getY1().getyRangeUnit()));
|
||||
result.setAggregates(
|
||||
toAggregateInternal(result.getYRangeUnit(), result.getYAxisScale(), request.getAggregates()));
|
||||
result.setY1(request.getY1());
|
||||
result.setY2(request.getY2());
|
||||
result.setAggregates(toAggregateInternal(request.getY1(), request.getY2(), request.getAggregates()));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static TimeRangeUnit toTimeRangeUnitInternal(final TimeRangeUnit yRangeUnit) {
|
||||
switch (yRangeUnit) {
|
||||
case AUTOMATIC:
|
||||
return TimeRangeUnit.AUTOMATIC;
|
||||
case MILLISECONDS:
|
||||
return TimeRangeUnit.MILLISECONDS;
|
||||
case SECONDS:
|
||||
return TimeRangeUnit.SECONDS;
|
||||
case MINUTES:
|
||||
return TimeRangeUnit.MINUTES;
|
||||
case HOURS:
|
||||
return TimeRangeUnit.HOURS;
|
||||
case DAYS:
|
||||
return TimeRangeUnit.DAYS;
|
||||
}
|
||||
throw new IllegalStateException("unhandled enum value: " + yRangeUnit);
|
||||
}
|
||||
|
||||
static AggregateHandlerCollection toAggregateInternal(final TimeRangeUnit yRangeUnit, final AxisScale yAxisScale,
|
||||
final Iterable<Aggregate> aggregates) {
|
||||
static AggregateHandlerCollection toAggregateInternal(final YAxisDefinition y1, final YAxisDefinition y2,
|
||||
final List<Aggregate> aggregates) {
|
||||
final AggregateHandlerCollection aggregateHandlerCollection = new AggregateHandlerCollection();
|
||||
|
||||
for (final Aggregate aggregate : aggregates) {
|
||||
@@ -70,14 +53,7 @@ class PlotSettingsTransformer {
|
||||
aggregateHandlerCollection.addAggregateHandler(new ParallelRequestsAggregate());
|
||||
break;
|
||||
case SCATTER:
|
||||
if (yRangeUnit == TimeRangeUnit.AUTOMATIC && yAxisScale == AxisScale.LINEAR) {
|
||||
// TODO need a second ScatterAggregateHandler for YRangeUnit() ==
|
||||
// TimeRangeUnitInternal.AUTOMATIC
|
||||
throw new UnsupportedOperationException(
|
||||
"linear axis with automatic y range does not work, use logarthmic y-axis, or define a y-axis range");
|
||||
} else {
|
||||
aggregateHandlerCollection.addAggregateHandler(new ScatterAggregateHandler());
|
||||
}
|
||||
aggregateHandlerCollection.addAggregateHandler(new ScatterAggregateHandler());
|
||||
break;
|
||||
case HISTOGRAM:
|
||||
aggregateHandlerCollection.addAggregateHandler(new HistogramHandler());
|
||||
@@ -92,6 +68,14 @@ class PlotSettingsTransformer {
|
||||
|
||||
aggregateHandlerCollection.updateAxisForHandlers();
|
||||
|
||||
// Note: this check is incomplete -> implement the todo and remove this
|
||||
if (y1.getRangeUnit() == TimeRangeUnit.AUTOMATIC && y1.getAxisScale() == AxisScale.LINEAR) {
|
||||
// TODO need a second ScatterAggregateHandler for YRangeUnit() ==
|
||||
// TimeRangeUnitInternal.AUTOMATIC
|
||||
throw new UnsupportedOperationException(
|
||||
"linear axis with automatic y range does not work, use logarthmic y-axis, or define a y-axis range");
|
||||
}
|
||||
|
||||
return aggregateHandlerCollection;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,9 @@ public class DataSeriesStats {
|
||||
private final int values;
|
||||
private final long maxValue;
|
||||
private final double average;
|
||||
private final int plottedValues;
|
||||
|
||||
public DataSeriesStats(final int values, final int plottedValues, final long maxValue, final double average) {
|
||||
public DataSeriesStats(final int values, final long maxValue, final double average) {
|
||||
this.values = values;
|
||||
this.plottedValues = plottedValues;
|
||||
this.maxValue = maxValue;
|
||||
this.average = average;
|
||||
}
|
||||
@@ -24,15 +22,6 @@ public class DataSeriesStats {
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of values in the date range <em>and</em> the y-range.
|
||||
*
|
||||
* @return number of plotted values
|
||||
*/
|
||||
public int getPlottedValues() {
|
||||
return plottedValues;
|
||||
}
|
||||
|
||||
public long getMaxValue() {
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
@@ -12,20 +12,17 @@ public class PlotResponseStats {
|
||||
|
||||
private double average;
|
||||
|
||||
private int plottedValues;
|
||||
|
||||
private List<DataSeriesStats> dataSeriesStats;
|
||||
|
||||
public PlotResponseStats() {
|
||||
super();
|
||||
}
|
||||
|
||||
public PlotResponseStats(final long maxValue, final int values, final int plottedValues, final double average,
|
||||
public PlotResponseStats(final long maxValue, final int values, final double average,
|
||||
final List<DataSeriesStats> dataSeriesStats) {
|
||||
|
||||
this.maxValue = maxValue;
|
||||
this.values = values;
|
||||
this.plottedValues = plottedValues;
|
||||
this.average = average;
|
||||
this.dataSeriesStats = dataSeriesStats;
|
||||
}
|
||||
@@ -46,14 +43,6 @@ public class PlotResponseStats {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public int getPlottedValues() {
|
||||
return plottedValues;
|
||||
}
|
||||
|
||||
public void setPlottedValues(final int plottedValues) {
|
||||
this.plottedValues = plottedValues;
|
||||
}
|
||||
|
||||
public double getAverage() {
|
||||
return average;
|
||||
}
|
||||
@@ -73,27 +62,25 @@ public class PlotResponseStats {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PlotResponseStats [maxValue=" + maxValue + ", values=" + values + ", average=" + average
|
||||
+ ", plottedValues=" + plottedValues + ", dataSeriesStats=" + dataSeriesStats + "]";
|
||||
+ ", dataSeriesStats=" + dataSeriesStats + "]";
|
||||
}
|
||||
|
||||
public static PlotResponseStats fromDataSeries(final List<DataSeries> dataSeries) {
|
||||
|
||||
int values = 0;
|
||||
int plottedValues = 0;
|
||||
long maxValue = 0;
|
||||
final List<DataSeriesStats> dataSeriesStats = new ArrayList<>();
|
||||
|
||||
for (final DataSeries dataSerie : dataSeries) {
|
||||
values += dataSerie.getValues();
|
||||
plottedValues += dataSerie.getPlottedValues();
|
||||
maxValue = Math.max(maxValue, dataSerie.getMaxValue());
|
||||
|
||||
dataSeriesStats.add(new DataSeriesStats(dataSerie.getValues(), dataSerie.getPlottedValues(),
|
||||
dataSerie.getMaxValue(), dataSerie.getAverage()));
|
||||
dataSeriesStats
|
||||
.add(new DataSeriesStats(dataSerie.getValues(), dataSerie.getMaxValue(), dataSerie.getAverage()));
|
||||
}
|
||||
|
||||
final double average = Math.round(DataSeriesStats.average(dataSeriesStats));
|
||||
|
||||
return new PlotResponseStats(maxValue, values, plottedValues, average, dataSeriesStats);
|
||||
return new PlotResponseStats(maxValue, values, average, dataSeriesStats);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user