create y-axis settings in aggregate handlers

This commit is contained in:
2019-11-23 18:31:14 +01:00
parent 8d55ef4e5f
commit 1cc39e3962
13 changed files with 262 additions and 189 deletions

View File

@@ -1,18 +1,18 @@
package org.lucares.recommind.logs;
import java.util.List;
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 {
public class AxisSettings {
public enum Type {
Number, Time
}
private String format = "";
private String label = "";
@@ -22,7 +22,7 @@ public class XAxisSettings {
private String from;
private String to;
private Type type = Type.Time;
private Type type = Type.Number;
private GnuplotAxis axis = GnuplotAxis.X1;
@@ -30,6 +30,9 @@ public class XAxisSettings {
private boolean ticsEnabled;
private boolean logscale;
private List<String> ticsLabels;
public String getFormat() {
return format;
@@ -94,42 +97,71 @@ public class XAxisSettings {
public double getTicIncrement() {
return ticIncrement;
}
public void setTicsEnabled(boolean ticsEnabled) {
this.ticsEnabled = ticsEnabled;
}
public boolean isTicsEnabled() {
return ticsEnabled;
}
public void setLogscale(boolean logscale) {
this.logscale = logscale;
}
public boolean isLogscale() {
return logscale;
}
public void setTics(List<String> ticsLabels) {
this.ticsLabels = ticsLabels;
}
public List<String> getTics() {
return ticsLabels;
}
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);
if (renderLabels) {
if (ticIncrement != 0) {
appendfln(result, "set %stics %f nomirror", axis, ticIncrement);
}
else if (ticsLabels != null && ticsLabels.size() > 0) {
appendfln(result,"set %stics(%s) nomirror", axis, String.join(", ", ticsLabels));
}else if(ticsEnabled) {
appendfln(result, "set %stics nomirror", axis);
}
if (StringUtils.isNotBlank(format)) {
appendfln(result, "set format %s \"%s\"", axis, format);
}
if (rotateLabel != 0) {
appendfln(result, "set %stics nomirror rotate by %d", axis, rotateLabel);
}
if (StringUtils.isNotBlank(label)) {
appendfln(result, "set %slabel \"%s\"", axis, label);
}
}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);
final String f = StringUtils.isEmpty(from) ? "" : "\""+from+"\"";
final String t = StringUtils.isEmpty(to) ? "" : "\""+to+"\"";
appendfln(result, "set %srange [%s:%s]", axis, f, t);
}
if (logscale) {
appendfln(result, "set logscale %s", axis);
}
return result.toString();
}
@@ -147,4 +179,6 @@ public class XAxisSettings {
return e.getMessage();
}
}
}

View File

@@ -0,0 +1,60 @@
package org.lucares.recommind.logs;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Collection;
import org.lucares.pdb.plot.api.AxisScale;
import org.lucares.recommind.logs.AxisSettings.Type;
public class AxisTime {
public static AxisSettings createXAxis(GnuplotSettings settings) {
AxisSettings result = new AxisSettings();
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;
}
public static AxisSettings createYAxis(GnuplotSettings settings, Collection<DataSeries> dataSeries) {
AxisSettings result = new AxisSettings();
result.setLabel("Duration");
result.setAxis(GnuplotAxis.Y1);
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();
result.setFrom(String.valueOf(min));
result.setTo(String.valueOf(max));
} else {
result.setFrom(String.valueOf(graphOffset));
}
result.setLogscale(settings.getYAxisScale() == AxisScale.LOG10);
result.setTics(YAxisTicks.computeYTicks(settings, dataSeries));
return result;
}
}

View File

@@ -3,11 +3,11 @@ package org.lucares.recommind.logs;
import java.util.Collection;
import java.util.List;
import org.lucares.pdb.plot.api.AxisScale;
import org.lucares.pdb.plot.api.Appender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GnuplotFileGenerator {
public class GnuplotFileGenerator implements Appender{
private static final Logger LOGGER = LoggerFactory.getLogger(GnuplotFileGenerator.class);
@@ -25,11 +25,25 @@ public class GnuplotFileGenerator {
//settings.getAggregates().addGnuplotDefinitions(result, dataSeries);
List<XAxisSettings> xAxisDefinitions = settings.getAggregates().getXAxisDefinitions(settings);
for (XAxisSettings xAxisSettings : xAxisDefinitions) {
appendln(result, xAxisSettings.toGnuplotDefinition(settings.isRenderLabels()));
final List<AxisSettings> xAxisDefinitions = settings.getAggregates().getXAxisDefinitions(settings, dataSeries);
for (AxisSettings axisSettings : xAxisDefinitions) {
appendln(result, axisSettings.toGnuplotDefinition(settings.isRenderLabels()));
}
final List<AxisSettings> yAxisDefinitions = settings.getAggregates().getYAxisDefinitions(settings, dataSeries);
if(dataSeries.isEmpty()) {
// If there is no data, then Gnuplot won't generate an image.
// Workaround is to explicitly specify the y-axis range.
// We choose a range for which no ticks are defined. This creates an empty y-axis.
yAxisDefinitions.forEach(s -> s.setFrom("0"));
yAxisDefinitions.forEach(s -> s.setFrom("-1"));
}
for (AxisSettings axisSettings : yAxisDefinitions) {
appendln(result, axisSettings.toGnuplotDefinition(settings.isRenderLabels()));
}
// final XAxisSettings xAxis = settings.getxAxisSettings();
// if (xAxis.getType() == Type.Time) {
@@ -41,27 +55,27 @@ public class GnuplotFileGenerator {
// 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()) {
final int min = Math.max(settings.getYRangeMin(), graphOffset);
final int max = settings.getYRangeMax();
appendfln(result, String.format("set yrange [\"%d\":\"%d\"]", min, max));
} else if(dataSeries.isEmpty()) {
// If there is no data, then Gnuplot won't generate an image.
// Workaround is to explicitly specify the y-axis range.
// We choose a range for which no ticks are defined. This creates an empty y-axis.
appendfln(result, "set yrange [\"%d\":\"%d\"]", 0, -1);
}else {
appendfln(result, "set yrange [\"" + graphOffset + "\":]");
}
switch (settings.getYAxisScale()) {
case LINEAR:
break;
case LOG10:
appendfln(result, "set logscale y");
break;
}
// 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();
// appendfln(result, String.format("set yrange [\"%d\":\"%d\"]", min, max));
// } else if(dataSeries.isEmpty()) {
// // If there is no data, then Gnuplot won't generate an image.
// // Workaround is to explicitly specify the y-axis range.
// // We choose a range for which no ticks are defined. This creates an empty y-axis.
// appendfln(result, "set yrange [\"%d\":\"%d\"]", 0, -1);
// }else {
// appendfln(result, "set yrange [\"" + graphOffset + "\":]");
// }
//
// switch (settings.getYAxisScale()) {
// case LINEAR:
// break;
// case LOG10:
// appendfln(result, "set logscale y");
// break;
// }
appendfln(result, "set grid");
appendfln(result, "set output \"%s\"", settings.getOutput().toAbsolutePath().toString().replace("\\", "/"));
@@ -77,10 +91,10 @@ public class GnuplotFileGenerator {
// appendfln(result, "set x2label \"\"");
// appendln(result, "set format x2 \"\"");
//
appendfln(result, "set ylabel \"\"");
appendln(result, "set format y \"\"");
appendln(result, "set y2label \"\"");
appendln(result, "set format y2 \"\"");
// appendfln(result, "set ylabel \"\"");
// appendln(result, "set format y \"\"");
// appendln(result, "set y2label \"\"");
// appendln(result, "set format y2 \"\"");
appendln(result, "set nokey");
} else if (!settings.isKeyOutside()) {
@@ -93,10 +107,10 @@ public class GnuplotFileGenerator {
appendln(result, "set bmargin 4"); // margin 4 -> 76
appendfln(result, "set tics font \",%d\"", GnuplotSettings.TICKS_FONT_SIZE);
appendln(result, YAxisTicks.computeYTicks(settings, dataSeries));
//appendln(result, YAxisTicks.computeYTicks(settings, dataSeries));
} else {
appendfln(result, "set tics font \",%d\"", GnuplotSettings.TICKS_FONT_SIZE);
appendln(result, YAxisTicks.computeYTicks(settings, dataSeries));
//appendln(result, YAxisTicks.computeYTicks(settings, dataSeries));
}
appendf(result, "plot ");
@@ -112,17 +126,7 @@ public class GnuplotFileGenerator {
return result.toString();
}
private void appendfln(final StringBuilder builder, final String format, final Object... args) {
builder.append(String.format(format + "\n", args));
}
private void appendln(final StringBuilder builder, final String string) {
builder.append(string + "\n");
}
private void appendf(final StringBuilder builder, final String format, final Object... args) {
builder.append(String.format(format, args));
}
}

View File

@@ -31,7 +31,7 @@ public class GnuplotSettings {
private AggregateHandlerCollection aggregates;
private boolean keyOutside = false;
private XAxisSettings xAxisSettings = new XAxisSettings();
private AxisSettings xAxisSettings = new AxisSettings();
private boolean renderLabels = true;
private int yRangeMin = -1;
private int yRangeMax = -1;
@@ -41,11 +41,11 @@ public class GnuplotSettings {
this.output = output;
}
public XAxisSettings getxAxisSettings() {
public AxisSettings getxAxisSettings() {
return xAxisSettings;
}
public void setxAxisSettings(final XAxisSettings xAxisSettings) {
public void setxAxisSettings(final AxisSettings xAxisSettings) {
this.xAxisSettings = xAxisSettings;
}

View File

@@ -6,7 +6,6 @@ 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.Iterator;

View File

@@ -1,35 +0,0 @@
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

@@ -9,13 +9,14 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
class YAxisTicks {
public static String computeYTicks(final GnuplotSettings settings, final Collection<DataSeries> dataSeries) {
String result = "";
public static List<String> computeYTicks(final GnuplotSettings settings, final Collection<DataSeries> dataSeries) {
List<String> result = new ArrayList<String>();
final long yRangeMax;
final long yRangeMin;
@@ -41,9 +42,7 @@ class YAxisTicks {
return result;
}
private static String computeLog10YTicks(final int height, final long yRangeMin, final long yRangeMax) {
final StringBuilder result = new StringBuilder();
result.append("set ylabel \"Duration\"\n");
private static List<String> computeLog10YTicks(final int height, final long yRangeMin, final long yRangeMax) {
final List<String> ticsLabels = Arrays.asList(//
"\"1ms\" 1", //
@@ -74,22 +73,20 @@ private static String computeLog10YTicks(final int height, final long yRangeMin,
"\"2d\" 172800000", //
"\"1 week\" 604800000", //
"\"2 week\" 1209600000.0", //
"\"4 week\" 2419200000.0" //
"\"4 week\" 2419200000.0", //
"\"3 month\" 7776000000.0", //
"\"1 year\" 31536000000.0", //
"\"5 year\" 157680000000.0", //
"\"10 year\" 315360000000.0"
);
result.append("set ytics (");
result.append(String.join(", ", ticsLabels));
result.append(")\n");
return result.toString();
return ticsLabels;
}
private static String computeLinearYTicks(final long height, final long yRangeMin, final long yRangeMax) {
final StringBuilder result = new StringBuilder();
result.append("set ylabel \"Duration\"\n");
private static List<String> computeLinearYTicks(final long height, final long yRangeMin, final long yRangeMax) {
final long plotHeight = height - GnuplotSettings.GNUPLOT_TOP_BOTTOM_MARGIN; // sum of top/bottom margin, see
// marker (1)
final long plotHeight = height - GnuplotSettings.GNUPLOT_TOP_BOTTOM_MARGIN;
final long maxLabels = plotHeight / (GnuplotSettings.TICKS_FONT_SIZE * 5);
final long range = yRangeMax - yRangeMin;
@@ -100,10 +97,7 @@ private static String computeLinearYTicks(final long height, final long yRangeMi
ticsLabels.add("\"" + msToTic(i, msPerLabel) + "\" " + i);
}
result.append("set ytics (");
result.append(String.join(", ", ticsLabels));
result.append(")\n");
return result.toString();
return ticsLabels;
}
private static long roundToLinearLabelSteps(final long msPerLabel) {
@@ -128,9 +122,9 @@ private static String msToTic(final long ms, final double msPerLabel) {
return ms + "ms";
} else if (ms < MINUTES.toMillis(1)) {
if (msPerLabel % 1000 == 0) {
return String.format("%ds", ms / 1_000);
return String.format(Locale.US,"%ds", ms / 1_000);
} else {
return String.format("%.1fs", ms / 1_000.0);
return String.format(Locale.US,"%.1fs", ms / 1_000.0);
}
} else if (ms < TimeUnit.HOURS.toMillis(1)) {