put y axis definition into its own object

This commit is contained in:
2020-02-09 17:16:27 +01:00
parent ed7cc9bee5
commit 859491e99e
28 changed files with 268 additions and 324 deletions

View File

@@ -8,6 +8,7 @@ import java.util.concurrent.TimeUnit;
import org.lucares.collections.LongList;
import org.lucares.pdb.api.DateTimeRange;
import org.lucares.pdb.plot.api.AxisScale;
import org.lucares.pdb.plot.api.YAxisDefinition;
import org.lucares.recommind.logs.AxisSettings.Type;
public class AxisTime {
@@ -40,25 +41,30 @@ public class AxisTime {
}
public static AxisSettings createYAxis(final GnuplotSettings settings, final Collection<DataSeries> dataSeries) {
final GnuplotAxis yAxis = GnuplotAxis.Y1; // TODO get yAxis as parameter
final AxisSettings result = new AxisSettings();
result.setLabel("Duration");
result.setType(Type.Duration);
result.setAxis(GnuplotAxis.Y1);
result.setAxis(yAxis);
result.setTicsEnabled(true);
final int graphOffset = settings.getYAxisScale() == AxisScale.LINEAR ? 0 : 1;
if (settings.hasYRange()) {
final int min = Math.max(settings.getYRangeMin(), graphOffset);
final int max = settings.getYRangeMax();
final YAxisDefinition yAxisDefinition = settings.getYAxisDefinition(yAxis);
final int graphOffset = yAxisDefinition.getAxisScale() == AxisScale.LINEAR ? 0 : 1;
if (yAxisDefinition.hasRange()) {
final long min = Math.max(yAxisDefinition.getRangeMinInMs(), graphOffset);
final long max = yAxisDefinition.getRangeMaxInMs();
result.setFrom(String.valueOf(min));
result.setTo(String.valueOf(max));
} else {
result.setFrom(String.valueOf(graphOffset));
}
result.setLogscale(settings.getYAxisScale() == AxisScale.LOG10);
result.setLogscale(yAxisDefinition.isLogscale());
result.setTics(YAxisTicks.computeYTicks(settings, dataSeries));
result.setTics(YAxisTicks.computeYTicks(settings, yAxis, dataSeries));
return result;
}

View File

@@ -7,13 +7,11 @@ class CsvSummary {
private final long maxValue;
private final AggregatorCollection aggregators;
private final double statsAverage;
private final int plottedValues;
public CsvSummary(final int values, final int plottedValues, final long maxValue, final double statsAverage,
public CsvSummary(final int values, final long maxValue, final double statsAverage,
final AggregatorCollection aggregators) {
super();
this.values = values;
this.plottedValues = plottedValues;
this.maxValue = maxValue;
this.statsAverage = statsAverage;
this.aggregators = aggregators;
@@ -29,16 +27,6 @@ class CsvSummary {
return values;
}
/**
* Number of plotted values in the selected date range <em>and</em> y-range.
*
* @see CsvSummary#getValues()
* @return number of plotted values
*/
public int getPlottedValues() {
return plottedValues;
}
public long getMaxValue() {
return maxValue;
}

View File

@@ -31,8 +31,6 @@ public interface DataSeries {
public int getValues();
public int getPlottedValues();
public long getMaxValue();
public double getAverage();

View File

@@ -48,11 +48,6 @@ public class FileBackedDataSeries implements DataSeries {
return csvSummary.getValues();
}
@Override
public int getPlottedValues() {
return csvSummary.getPlottedValues();
}
@Override
public long getMaxValue() {
return csvSummary.getMaxValue();

View File

@@ -4,7 +4,7 @@ import java.nio.file.Path;
import org.lucares.pdb.api.DateTimeRange;
import org.lucares.pdb.plot.api.AggregateHandlerCollection;
import org.lucares.pdb.plot.api.AxisScale;
import org.lucares.pdb.plot.api.YAxisDefinition;
public class GnuplotSettings {
@@ -27,14 +27,13 @@ public class GnuplotSettings {
// set output "datausage.png"
private final Path output;
private AxisScale yAxisScale;
private YAxisDefinition y1;
private YAxisDefinition y2;
private AggregateHandlerCollection aggregates;
private boolean keyOutside = false;
private AxisSettings xAxisSettings = new AxisSettings();
private boolean renderLabels = true;
private int yRangeMin = -1;
private int yRangeMax = -1;
private DateTimeRange dateTimeRange;
public GnuplotSettings(final Path output) {
@@ -93,14 +92,6 @@ public class GnuplotSettings {
return output;
}
public void setYAxisScale(final AxisScale yAxisScale) {
this.yAxisScale = yAxisScale;
}
public AxisScale getYAxisScale() {
return yAxisScale;
}
public void setAggregates(final AggregateHandlerCollection aggregates) {
this.aggregates = aggregates;
}
@@ -125,24 +116,23 @@ public class GnuplotSettings {
return renderLabels;
}
public boolean hasYRange() {
return yRangeMin >= 0 && yRangeMax >= 0 && yRangeMin < yRangeMax;
public YAxisDefinition getY1() {
return y1;
}
public void setYRange(final int yRangeMin, final int yRangeMax) {
this.yRangeMin = yRangeMin;
this.yRangeMax = yRangeMax;
public void setY1(final YAxisDefinition y1) {
this.y1 = y1;
}
public int getYRangeMin() {
return yRangeMin;
public YAxisDefinition getY2() {
return y2;
}
public int getYRangeMax() {
return yRangeMax;
public void setY2(final YAxisDefinition y2) {
this.y2 = y2;
}
public void setDateTimeRange(DateTimeRange dateTimeRange) {
public void setDateTimeRange(final DateTimeRange dateTimeRange) {
this.dateTimeRange = dateTimeRange;
}
@@ -150,6 +140,17 @@ public class GnuplotSettings {
return dateTimeRange;
}
public YAxisDefinition getYAxisDefinition(final GnuplotAxis yAxis) {
switch (yAxis) {
case Y1:
return y1;
case Y2:
return y2;
default:
throw new IllegalArgumentException("Unexpected value: " + yAxis);
}
}
// plot 'sample.txt' using 1:2 title 'Bytes' with linespoints 2
}

View File

@@ -24,7 +24,6 @@ import org.lucares.pdb.api.Tags;
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.TimeRangeUnit;
import org.lucares.performance.db.PerformanceDb;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -108,10 +107,10 @@ public class Plotter {
gnuplotSettings.setWidth(width);
gnuplotSettings.setDateTimeRange(plotSettings.dateRange());
gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale());
gnuplotSettings.setY1(plotSettings.getY1());
gnuplotSettings.setY2(plotSettings.getY2());
gnuplotSettings.setAggregates(plotSettings.getAggregates());
defineYRange(gnuplotSettings, plotSettings.getYRangeMin(), plotSettings.getYRangeMax(),
plotSettings.getYRangeUnit());
gnuplotSettings.setKeyOutside(plotSettings.isKeyOutside());
gnuplot.plot(gnuplotSettings, dataSeries);
}
@@ -124,11 +123,9 @@ public class Plotter {
gnuplotSettings.setHeight(plotSettings.getThumbnailMaxHeight());
gnuplotSettings.setWidth(plotSettings.getThumbnailMaxWidth());
gnuplotSettings.setDateTimeRange(plotSettings.dateRange());
gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale());
gnuplotSettings.setY1(plotSettings.getY1());
gnuplotSettings.setY2(plotSettings.getY2());
gnuplotSettings.setAggregates(plotSettings.getAggregates());
defineYRange(gnuplotSettings, plotSettings.getYRangeMin(), plotSettings.getYRangeMax(),
plotSettings.getYRangeUnit());
gnuplotSettings.setKeyOutside(false);
gnuplotSettings.renderLabels(false);
gnuplot.plot(gnuplotSettings, dataSeries);
@@ -148,16 +145,6 @@ public class Plotter {
}
}
private void defineYRange(final GnuplotSettings gnuplotSettings, final int yRangeMin, final int yRangeMax,
final TimeRangeUnit yRangeUnit) {
if (yRangeUnit != TimeRangeUnit.AUTOMATIC) {
final int min = yRangeUnit.toMilliSeconds(yRangeMin);
final int max = yRangeUnit.toMilliSeconds(yRangeMax);
gnuplotSettings.setYRange(min, max);
}
}
private static CsvSummary toCsvDeduplicated(final GroupResult groupResult, final Path tmpDir,
final OffsetDateTime dateFrom, final OffsetDateTime dateTo, final PlotSettings plotSettings)
throws IOException {
@@ -169,16 +156,11 @@ public class Plotter {
final long toEpochMilli = dateTo.toInstant().toEpochMilli();
final boolean useMillis = (toEpochMilli - fromEpochMilli) < TimeUnit.MINUTES.toMillis(5);
final long minValue = plotSettings.getYRangeUnit() == TimeRangeUnit.AUTOMATIC ? 0
: plotSettings.getYRangeUnit().toMilliSeconds(plotSettings.getYRangeMin());
final long maxValue = plotSettings.getYRangeUnit() == TimeRangeUnit.AUTOMATIC ? Long.MAX_VALUE
: plotSettings.getYRangeUnit().toMilliSeconds(plotSettings.getYRangeMax());
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)
int plottedValues = 0;
final int plottedValues = 0;
long statsMaxValue = 0;
double statsCurrentAverage = 0.0;
long ignoredValues = 0;
@@ -204,22 +186,14 @@ public class Plotter {
// compute average (important to do this after 'count' has been incremented)
statsCurrentAverage = statsCurrentAverage + (value - statsCurrentAverage) / count;
// check if value is in the selected y-range
final boolean valueIsInYRange = value < minValue || value > maxValue;
if (valueIsInYRange) {
ignoredValues++;
} else {
plottedValues++;
}
aggregator.addValue(groupedBy, valueIsInYRange, epochMilli, value);
aggregator.addValue(groupedBy, epochMilli, value);
}
}
METRICS_LOGGER.debug("wrote {} values to csv in: {}ms (ignored {} values) use millis: {}, grouping={}",
plottedValues, (System.nanoTime() - start) / 1_000_000.0, ignoredValues, Boolean.toString(useMillis),
groupResult.getGroupedBy().asString());
return new CsvSummary(count, plottedValues, statsMaxValue, statsCurrentAverage, aggregator);
return new CsvSummary(count, statsMaxValue, statsCurrentAverage, aggregator);
}
@@ -229,17 +203,13 @@ public class Plotter {
}
static String title(final Tags tags, final CsvSummary csvSummary) {
// FIXME title must be computed by the AggregateHandler, because it is the only
// one knowing how many values are plotted
final StringBuilder result = new StringBuilder(tags.asValueString());
final int values = csvSummary.getValues();
final int plottedValues = csvSummary.getPlottedValues();
result.append(" (");
if (plottedValues != values) {
result.append(String.format("%,d / %,d", plottedValues, values));
} else {
result.append(String.format("%,d", values));
}
result.append(String.format("%,d", values));
result.append(")");
return result.toString();

View File

@@ -12,23 +12,28 @@ import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import org.lucares.pdb.plot.api.YAxisDefinition;
class YAxisTicks {
public static List<String> computeYTicks(final GnuplotSettings settings, final Collection<DataSeries> dataSeries) {
public static List<String> computeYTicks(final GnuplotSettings settings, final GnuplotAxis yAxis,
final Collection<DataSeries> dataSeries) {
List<String> result = new ArrayList<String>();
final YAxisDefinition yAxisDefinition = settings.getYAxisDefinition(yAxis);
final long yRangeMax;
final long yRangeMin;
if (settings.hasYRange()) {
yRangeMax = settings.getYRangeMax();
yRangeMin = settings.getYRangeMin();
if (yAxisDefinition.hasRange()) {
yRangeMin = yAxisDefinition.getRangeMinInMs();
yRangeMax = yAxisDefinition.getRangeMaxInMs();
} else {
yRangeMax = DataSeries.maxValue(dataSeries);
yRangeMin = 0;
yRangeMax = DataSeries.maxValue(dataSeries);
}
final int height = settings.getHeight();
switch (settings.getYAxisScale()) {
switch (yAxisDefinition.getAxisScale()) {
case LINEAR:
result = computeLinearYTicks(height, yRangeMin, yRangeMax);
break;
@@ -81,16 +86,17 @@ class YAxisTicks {
return ticsLabels;
}
private static List<String> computeLinearYTicks(final long height, final long yRangeMin, final long yRangeMax) {
private static List<String> computeLinearYTicks(final long height, final long yRangeMinInMs,
final long yRangeMaxInMs) {
final long plotHeight = height - GnuplotSettings.GNUPLOT_TOP_BOTTOM_MARGIN;
final long maxLabels = plotHeight / (GnuplotSettings.TICKS_FONT_SIZE * 5);
final long range = yRangeMax - yRangeMin;
final long range = yRangeMaxInMs - yRangeMinInMs;
final long msPerLabel = roundToLinearLabelSteps(range / maxLabels);
final List<String> ticsLabels = new ArrayList<>();
for (long i = yRangeMin; i <= yRangeMax; i += msPerLabel) {
for (long i = yRangeMinInMs; i <= yRangeMaxInMs; i += msPerLabel) {
ticsLabels.add("\"" + msToTic(i, msPerLabel) + "\" " + i);
}