move definition of x-axis to the aggregate handlers

This commit is contained in:
2019-11-23 14:28:18 +01:00
parent 84e5f99c4f
commit 82a961dbaf
13 changed files with 305 additions and 99 deletions

View File

@@ -5,13 +5,18 @@ import java.util.Collection;
import java.util.Optional;
import org.lucares.recommind.logs.DataSeries;
import org.lucares.recommind.logs.GnuplotSettings;
import org.lucares.recommind.logs.LineStyle;
import org.lucares.recommind.logs.XAxisSettings;
public interface AggregateHandler {
Aggregate getAggregateType();
void addGnuplotDefinitions(StringBuilder result, String separator, Collection<DataSeries> dataSeries);
@Deprecated
void addGnuplotDefinitions(StringBuilder result, Collection<DataSeries> dataSeries);
XAxisSettings createXAxisSettings(GnuplotSettings settings);
default void appendln(final StringBuilder builder, final String string) {
builder.append(string + "\n");

View File

@@ -9,6 +9,10 @@ import java.util.List;
import java.util.Optional;
import org.lucares.recommind.logs.DataSeries;
import org.lucares.recommind.logs.GnuplotSettings;
import org.lucares.recommind.logs.XAxisSettings;
import org.lucares.utils.CollectionUtils;
import org.lucares.utils.CollectionUtils.Compare;
public class AggregateHandlerCollection {
private static final Comparator<AggregateHandler> COMPARATOR = Comparator.comparing(AggregateHandler::getAggregateType);
@@ -20,11 +24,28 @@ public class AggregateHandlerCollection {
Collections.sort(aggregateHandlers, COMPARATOR);
}
public void addGnuplotDefinitions(StringBuilder result, String datafileSeparator, Collection<DataSeries> dataSeries) {
public void addGnuplotDefinitions(StringBuilder result, Collection<DataSeries> dataSeries) {
for (AggregateHandler handler : aggregateHandlers) {
handler.addGnuplotDefinitions(result, datafileSeparator, dataSeries);
handler.addGnuplotDefinitions(result, dataSeries);
}
}
public List<XAxisSettings> getXAxisDefinitions(GnuplotSettings settings) {
List<XAxisSettings> result = new ArrayList<>();
for (AggregateHandler handler : aggregateHandlers) {
XAxisSettings xaxis = handler.createXAxisSettings(settings);
final Compare<XAxisSettings> compare = Compare.compare(XAxisSettings::getType, xaxis.getType())
.thenCompare(XAxisSettings::getLabel, xaxis.getLabel());
if (!CollectionUtils.contains(result, compare)) {
result.add(xaxis);
}
}
return result;
}
public AggregatorCollection createCustomAggregator(Path tmpDir, PlotSettings plotSettings, long fromEpochMilli,
long toEpochMilli) {
@@ -61,4 +82,5 @@ public class AggregateHandlerCollection {
}
}

View File

@@ -5,7 +5,11 @@ import java.util.Collection;
import java.util.Optional;
import org.lucares.recommind.logs.DataSeries;
import org.lucares.recommind.logs.GnuplotAxis;
import org.lucares.recommind.logs.GnuplotSettings;
import org.lucares.recommind.logs.LineStyle;
import org.lucares.recommind.logs.XAxisSettings;
import org.lucares.recommind.logs.XAxisSettings.Type;
public class CumulativeDistributionHandler implements AggregateHandler {
@@ -19,7 +23,7 @@ public class CumulativeDistributionHandler implements AggregateHandler {
}
@Override
public void addGnuplotDefinitions(final StringBuilder result, final String separator,
public void addGnuplotDefinitions(final StringBuilder result,
final Collection<DataSeries> dataSeries) {
appendln(result, "set x2label \"Cumulative Distribution\"");
@@ -27,6 +31,18 @@ public class CumulativeDistributionHandler implements AggregateHandler {
appendln(result, "set x2tics 5");
appendln(result, "set x2range [\"0\":\"100\"]");
}
@Override
public XAxisSettings createXAxisSettings(GnuplotSettings settings) {
XAxisSettings result = new XAxisSettings();
result.setLabel("Cumulative Distribution");
result.setType(Type.Number);
result.setAxis(GnuplotAxis.X2); // TODO determine automatically
result.setFormat("%.0f%%");
result.setTicIncrement(5);
result.setFrom("0");
result.setTo("100");
return result;
}
@Override
public void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle, Optional<String> title) {

View File

@@ -6,16 +6,24 @@ import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.lucares.recommind.logs.DataSeries;
import org.lucares.recommind.logs.GnuplotSettings;
import org.lucares.recommind.logs.LineStyle;
import org.lucares.recommind.logs.XAxisSettings;
import org.lucares.recommind.logs.XAxisTime;
public class ParallelRequestsAggregate implements AggregateHandler {
@Override
public void addGnuplotDefinitions(final StringBuilder result, final String separator,
public void addGnuplotDefinitions(final StringBuilder result,
final Collection<DataSeries> dataSeries) {
appendln(result, "set y2label \"Parallel Requests\"");
appendln(result, "set y2tics");
}
@Override
public XAxisSettings createXAxisSettings(GnuplotSettings settings) {
return XAxisTime.create(settings);
}
@Override
public void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle,

View File

@@ -6,16 +6,27 @@ import java.util.Optional;
import org.lucares.recommind.logs.DataSeries;
import org.lucares.recommind.logs.GnuplotLineType;
import org.lucares.recommind.logs.GnuplotSettings;
import org.lucares.recommind.logs.LineStyle;
import org.lucares.recommind.logs.XAxisSettings;
import org.lucares.recommind.logs.XAxisTimeTics;
import org.lucares.recommind.logs.XAxisSettings.Type;
import org.lucares.recommind.logs.XAxisTime;
public class ScatterAggregateHandler implements AggregateHandler {
@Override
public void addGnuplotDefinitions(StringBuilder result, String separator, Collection<DataSeries> dataSeries) {
public void addGnuplotDefinitions(StringBuilder result, Collection<DataSeries> dataSeries) {
// TODO Auto-generated method stub
}
@Override
public XAxisSettings createXAxisSettings(GnuplotSettings settings) {
return XAxisTime.create(settings);
}
@Override
public void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle, Optional<String> title) {

View File

@@ -1,22 +1,28 @@
package org.lucares.recommind.logs;
public enum GnuplotAxis {
X1Y1("x1y1"),
X1("x", ""),
X1Y2("x1y2"),
X2("x2", "x2"),
X2Y1("x2y1"),
Y1("y", "y"),
X2Y2("x2y2");
Y2("y2", "y2");
private String axis;
private String axisNameForTics;
private GnuplotAxis(String axis) {
private GnuplotAxis(String axis, String axisNameForTics) {
this.axis = axis;
this.axisNameForTics = axisNameForTics;
}
@Override
public String toString() {
return axis;
}
public String getAxisNameForTics() {
return axisNameForTics;
}
}

View File

@@ -1,11 +1,16 @@
package org.lucares.recommind.logs;
import java.util.Collection;
import java.util.List;
import org.lucares.pdb.plot.api.AxisScale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GnuplotFileGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(GnuplotFileGenerator.class);
private static final int KEY_FONT_SIZE = 10;
public String generate(final GnuplotSettings settings, final Collection<DataSeries> dataSeries) {
@@ -16,20 +21,25 @@ public class GnuplotFileGenerator {
settings.getHeight());
appendfln(result, "set datafile separator \"%s\"", settings.getDatafileSeparator());
settings.getAggregates().addGnuplotDefinitions(result, settings.getDatafileSeparator(), dataSeries);
appendfln(result, "set timefmt '%s'", settings.getTimefmt());
final XAxisSettings xAxis = settings.getxAxisSettings();
if (xAxis.isxDataTime()) {
appendfln(result, "set xdata time");
appendln(result, XAxisTimeTicks.computeXTimeIncrements(settings));
appendfln(result, "set format x \"%s\"", xAxis.getFormatX());
}
appendfln(result, "set xtics nomirror rotate by %d", xAxis.getRotateXAxisLabel());
appendfln(result, "set xlabel \"%s\"", xAxis.getXlabel());
appendfln(result, "set xrange [\"%s\":\"%s\"]", xAxis.getFrom(), xAxis.getTo());
//settings.getAggregates().addGnuplotDefinitions(result, dataSeries);
List<XAxisSettings> xAxisDefinitions = settings.getAggregates().getXAxisDefinitions(settings);
for (XAxisSettings xAxisSettings : xAxisDefinitions) {
appendln(result, xAxisSettings.toGnuplotDefinition(settings.isRenderLabels()));
}
// final XAxisSettings xAxis = settings.getxAxisSettings();
// if (xAxis.getType() == Type.Time) {
// appendfln(result, "set xdata time");
// appendln(result, XAxisTimeTics.computeXTimeIncrements(settings));
// appendfln(result, "set format x \"%s\"", xAxis.getFormat());
// }
// appendfln(result, "set xtics nomirror rotate by %d", xAxis.getRotateXAxisLabel());
// appendfln(result, "set xlabel \"%s\"", xAxis.getLabel());
// appendfln(result, "set xrange [\"%s\":\"%s\"]", xAxis.getFrom(), xAxis.getTo());
final int graphOffset = settings.getYAxisScale() == AxisScale.LINEAR ? 0 : 1;
if (settings.hasYRange()) {
@@ -62,11 +72,11 @@ public class GnuplotFileGenerator {
appendfln(result, "set key font \",%d\"", KEY_FONT_SIZE);
if (!settings.isRenderLabels()) {
appendfln(result, "set format x \"\"");
appendfln(result, "set xlabel \"\"");
appendfln(result, "set x2label \"\"");
appendln(result, "set format x2 \"\"");
// appendfln(result, "set format x \"\"");
// appendfln(result, "set xlabel \"\"");
// appendfln(result, "set x2label \"\"");
// appendln(result, "set format x2 \"\"");
//
appendfln(result, "set ylabel \"\"");
appendln(result, "set format y \"\"");
appendln(result, "set y2label \"\"");
@@ -97,6 +107,8 @@ public class GnuplotFileGenerator {
// render images when there are not data points on it.
appendf(result, "-1 with lines notitle");
LOGGER.info("{}", result);
return result.toString();
}

View File

@@ -2,6 +2,7 @@ package org.lucares.recommind.logs;
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;
@@ -34,6 +35,7 @@ public class GnuplotSettings {
private boolean renderLabels = true;
private int yRangeMin = -1;
private int yRangeMax = -1;
private DateTimeRange dateTimeRange;
public GnuplotSettings(final Path output) {
this.output = output;
@@ -140,6 +142,14 @@ public class GnuplotSettings {
return yRangeMax;
}
public void setDateTimeRange(DateTimeRange dateTimeRange) {
this.dateTimeRange = dateTimeRange;
}
public DateTimeRange getDateTimeRange() {
return dateTimeRange;
}
// plot 'sample.txt' using 1:2 title 'Bytes' with linespoints 2
}

View File

@@ -108,7 +108,7 @@ public class Plotter {
final GnuplotSettings gnuplotSettings = new GnuplotSettings(outputFile);
gnuplotSettings.setHeight(height);
gnuplotSettings.setWidth(width);
defineXAxis(gnuplotSettings, plotSettings.dateRange());
gnuplotSettings.setDateTimeRange(plotSettings.dateRange());
gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale());
gnuplotSettings.setAggregates(plotSettings.getAggregates());
@@ -125,7 +125,7 @@ public class Plotter {
final GnuplotSettings gnuplotSettings = new GnuplotSettings(thumbnail);
gnuplotSettings.setHeight(plotSettings.getThumbnailMaxHeight());
gnuplotSettings.setWidth(plotSettings.getThumbnailMaxWidth());
defineXAxis(gnuplotSettings, plotSettings.dateRange());
gnuplotSettings.setDateTimeRange(plotSettings.dateRange());
gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale());
gnuplotSettings.setAggregates(plotSettings.getAggregates());
@@ -160,33 +160,7 @@ public class Plotter {
}
}
private void defineXAxis(final GnuplotSettings gnuplotSettings, final DateTimeRange dateTimeRange) {
final OffsetDateTime minDate = dateTimeRange.getStart();
final OffsetDateTime maxDate = dateTimeRange.getEnd();
String formatX;
int rotateX;
String formattedMinDate;
String formattedMaxDate;
if (minDate.until(maxDate, ChronoUnit.WEEKS) > 1) {
formatX = "%Y-%m-%d";
rotateX = 0;
} else if (minDate.until(maxDate, ChronoUnit.SECONDS) > 30) {
formatX = "%Y-%m-%d\\n%H:%M:%S";
rotateX = gnuplotSettings.getxAxisSettings().getRotateXAxisLabel();
} else {
formatX = "%Y-%m-%d\\n%H:%M:%.3S";
rotateX = gnuplotSettings.getxAxisSettings().getRotateXAxisLabel();
}
formattedMinDate = String.valueOf(minDate.toEpochSecond());
formattedMaxDate = String.valueOf(maxDate.toEpochSecond());
gnuplotSettings.getxAxisSettings().setFormatX(formatX);
gnuplotSettings.getxAxisSettings().setRotateXAxisLabel(rotateX);
gnuplotSettings.getxAxisSettings().setFrom(formattedMinDate);
gnuplotSettings.getxAxisSettings().setTo(formattedMaxDate);
gnuplotSettings.getxAxisSettings().setDateTimeRange(dateTimeRange);
}
private static CsvSummary toCsvDeduplicated(final GroupResult groupResult, final Path tmpDir,
final OffsetDateTime dateFrom, final OffsetDateTime dateTo, final PlotSettings plotSettings) throws IOException {

View File

@@ -1,56 +1,58 @@
package org.lucares.recommind.logs;
import org.apache.commons.lang3.StringUtils;
import org.lucares.pdb.api.DateTimeRange;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class XAxisSettings {
// set xdata time
private boolean xDataTime = true;
public enum Type {
Number, Time
}
private String format = "";
// set format for x-axis
private String formatX = "%Y-%m-%d\\n%H:%M:%S";
private String label = "";
// set xlabel
private String xlabel = "Time";
// set xtics rotation in degree
private int rotateXAxisLabel = 0;
private int rotateLabel = 0;
private String from;
private String to;
private DateTimeRange dateTimeRange;
private Type type = Type.Time;
public boolean isxDataTime() {
return xDataTime;
private GnuplotAxis axis = GnuplotAxis.X1;
private double ticIncrement;
private boolean ticsEnabled;
public String getFormat() {
return format;
}
public void setxDataTime(boolean xDataTime) {
this.xDataTime = xDataTime;
public void setFormat(String format) {
this.format = format;
}
public String getFormatX() {
return formatX;
public String getLabel() {
return label;
}
public void setFormatX(String formatX) {
this.formatX = formatX;
}
public String getXlabel() {
return xlabel;
}
public void setXlabel(String xlabel) {
this.xlabel = xlabel;
public void setLabel(String label) {
this.label = label;
}
public int getRotateXAxisLabel() {
return rotateXAxisLabel;
return rotateLabel;
}
public void setRotateXAxisLabel(int rotateXAxisLabel) {
this.rotateXAxisLabel = rotateXAxisLabel;
public void setRotateLabel(int rotateLabel) {
this.rotateLabel = rotateLabel;
}
public String getFrom() {
@@ -69,18 +71,80 @@ public class XAxisSettings {
this.to = to;
}
public void setDateTimeRange(DateTimeRange dateTimeRange) {
this.dateTimeRange = dateTimeRange;
public Type getType() {
return type;
}
public DateTimeRange getDateTimeRange() {
return dateTimeRange;
public void setType(Type type) {
this.type = type;
}
public GnuplotAxis getAxis() {
return axis;
}
public void setAxis(GnuplotAxis axis) {
this.axis = axis;
}
public void setTicIncrement(double ticIncrement) {
this.ticIncrement = ticIncrement;
}
public double getTicIncrement() {
return ticIncrement;
}
public void setTicsEnabled(boolean ticsEnabled) {
this.ticsEnabled = ticsEnabled;
}
public boolean isTicsEnabled() {
return ticsEnabled;
}
public String toGnuplotDefinition(boolean renderLabels) {
StringBuilder result = new StringBuilder();
if (type == Type.Time) {
appendfln(result, "set %sdata time", axis);
}
if (ticIncrement != 0) {
appendfln(result, "set %stics %f", axis, ticIncrement);
}
if (StringUtils.isNotBlank(format) && renderLabels) {
appendfln(result, "set format %s \"%s\"", axis, format);
}else {
appendfln(result, "set format %s \"\"", axis);
}
if (rotateLabel != 0) {
appendfln(result, "set %stics nomirror rotate by %d", axis, rotateLabel);
}
if (StringUtils.isNotBlank(label) && renderLabels) {
appendfln(result, "set %slabel \"%s\"", axis, label);
}else {
appendfln(result, "set %slabel \"\"", axis);
}
if (!StringUtils.isAllBlank(from, to)) {
appendfln(result, "set %srange [\"%s\":\"%s\"]", axis, from, to);
}
return result.toString();
}
private void appendfln(final StringBuilder builder, final String format, final Object... args) {
builder.append(String.format(format + "\n", args));
}
@Override
public String toString() {
return "XAxisSettings [xDataTime=" + xDataTime + ", formatX=" + formatX + ", xlabel=" + xlabel
+ ", rotateXAxisLabel=" + rotateXAxisLabel + ", from=" + from + ", to=" + to + ", dateTimeRange="+dateTimeRange+"]";
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.writeValueAsString(this);
} catch (JsonProcessingException e) {
return e.getMessage();
}
}
}

View File

@@ -0,0 +1,35 @@
package org.lucares.recommind.logs;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import org.lucares.recommind.logs.XAxisSettings.Type;
public class XAxisTime {
public static XAxisSettings create(GnuplotSettings settings) {
XAxisSettings result = new XAxisSettings();
final OffsetDateTime minDate = settings.getDateTimeRange().getStart();
final OffsetDateTime maxDate = settings.getDateTimeRange().getEnd();
final String formatX;
if (minDate.until(maxDate, ChronoUnit.WEEKS) > 1) {
formatX = "%Y-%m-%d";
} else if (minDate.until(maxDate, ChronoUnit.SECONDS) > 30) {
formatX = "%Y-%m-%d\\n%H:%M:%S";
} else {
formatX = "%Y-%m-%d\\n%H:%M:%.3S";
}
final String formattedMinDate = String.valueOf(minDate.toEpochSecond());
final String formattedMaxDate = String.valueOf(maxDate.toEpochSecond());
result.setLabel("Time");
result.setType(Type.Time);
result.setTicsEnabled(true);
result.setFormat(formatX);
result.setFrom(formattedMinDate);
result.setTo(formattedMaxDate);
result.setTicIncrement(XAxisTimeTics.computeTimeTicIncrement(settings.getWidth(), settings.getDateTimeRange()));
return result;
}
}

View File

@@ -5,23 +5,31 @@ import java.util.concurrent.TimeUnit;
import org.lucares.collections.LongList;
import org.lucares.pdb.api.DateTimeRange;
public class XAxisTimeTicks {
public class XAxisTimeTics {
public static String computeXTimeIncrements(GnuplotSettings settings) {
DateTimeRange dateTimeRange = settings.getDateTimeRange();
return computeXTimeIncrements(settings.getWidth(), dateTimeRange);
}
public static String computeXTimeIncrements(int width, DateTimeRange dateTimeRange) {
DateTimeRange dateTimeRange = settings.getxAxisSettings().getDateTimeRange();
final double ticIncrement = computeTimeTicIncrement(width, dateTimeRange);
return "set xtics "+ ticIncrement;
}
public static double computeTimeTicIncrement(int width, DateTimeRange dateTimeRange) {
final long startEpochMilli = dateTimeRange.getStartEpochMilli();
final long endEpochMilli = dateTimeRange.getEndEpochMilli();
final long rangeInMs = endEpochMilli - startEpochMilli + 1;
int widthInPx = settings.getWidth() - GnuplotSettings.GNUPLOT_LEFT_RIGHT_MARGIN;
int widthInPx = width - GnuplotSettings.GNUPLOT_LEFT_RIGHT_MARGIN;
final long maxLabels = Math.max(1, widthInPx / (GnuplotSettings.TICKS_FONT_SIZE * 8));
final long tickIncrement = roundToTickIncrement(rangeInMs / maxLabels);
return "set xtics "+ tickIncrement/1000.0;
return tickIncrement/1000.0;
}
private static long roundToTickIncrement(long milliseconds) {