automatically determine which axis a plot needs

This commit is contained in:
2019-11-24 08:18:52 +01:00
parent 3048f67e9a
commit 892d5a6d08
9 changed files with 137 additions and 61 deletions

View File

@@ -6,26 +6,49 @@ import java.util.Optional;
import org.lucares.recommind.logs.AxisSettings; import org.lucares.recommind.logs.AxisSettings;
import org.lucares.recommind.logs.DataSeries; import org.lucares.recommind.logs.DataSeries;
import org.lucares.recommind.logs.GnuplotAxis;
import org.lucares.recommind.logs.GnuplotSettings; import org.lucares.recommind.logs.GnuplotSettings;
import org.lucares.recommind.logs.LineStyle; import org.lucares.recommind.logs.LineStyle;
public interface AggregateHandler extends Appender { public abstract class AggregateHandler implements Appender {
private GnuplotAxis xAxis = GnuplotAxis.X1;
Aggregate getAggregateType(); private GnuplotAxis yAxis = GnuplotAxis.Y1;
public GnuplotAxis getxAxis() {
return xAxis;
}
AxisSettings createXAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries); public void setxAxis(GnuplotAxis xAxis) {
this.xAxis = xAxis;
}
public GnuplotAxis getyAxis() {
return yAxis;
}
public void setyAxis(GnuplotAxis yAxis) {
this.yAxis = yAxis;
}
protected String gnuplotXYAxis() {
return xAxis.getAxisNameForPlots()+yAxis.getAxisNameForPlots();
}
abstract Aggregate getAggregateType();
abstract AxisSettings createXAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries);
abstract AxisSettings createYAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries);
abstract void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle, Optional<String> title);
abstract CustomAggregator createCustomAggregator(Path tmpDir, PlotSettings plotSettings, long fromEpochMilli,
long toEpochMilli);
protected String gnuplotTitle(Optional<String> title) {
AxisSettings createYAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries); return title.isPresent() ? "title '" + title.get() + "'" : "notitle";
}
default String gnuplotTitle(Optional<String> title) {
return title.isPresent() ? "title '"+title.get()+"'": "notitle";
}
void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle, Optional<String> title);
CustomAggregator createCustomAggregator(Path tmpDir, PlotSettings plotSettings, long fromEpochMilli, long toEpochMilli);
} }

View File

@@ -9,10 +9,12 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.lucares.recommind.logs.DataSeries; import org.lucares.recommind.logs.DataSeries;
import org.lucares.recommind.logs.GnuplotAxis;
import org.lucares.recommind.logs.GnuplotSettings; import org.lucares.recommind.logs.GnuplotSettings;
import org.lucares.recommind.logs.AxisSettings; import org.lucares.recommind.logs.AxisSettings;
import org.lucares.utils.CollectionUtils; import org.lucares.utils.CollectionUtils;
import org.lucares.utils.CollectionUtils.Compare; import org.lucares.utils.CollectionUtils.Compare;
import org.lucares.utils.Preconditions;
public class AggregateHandlerCollection { public class AggregateHandlerCollection {
private static final Comparator<AggregateHandler> COMPARATOR = Comparator.comparing(AggregateHandler::getAggregateType); private static final Comparator<AggregateHandler> COMPARATOR = Comparator.comparing(AggregateHandler::getAggregateType);
@@ -29,13 +31,23 @@ public class AggregateHandlerCollection {
public List<AxisSettings> getXAxisDefinitions(GnuplotSettings settings, Collection<DataSeries> dataSeries) { public List<AxisSettings> getXAxisDefinitions(GnuplotSettings settings, Collection<DataSeries> dataSeries) {
List<AxisSettings> result = new ArrayList<>(); List<AxisSettings> result = new ArrayList<>();
for (AggregateHandler handler : aggregateHandlers) { for (AggregateHandler handler : aggregateHandlers) {
AxisSettings xaxis = handler.createXAxisSettings(settings, dataSeries); AxisSettings axis = handler.createXAxisSettings(settings, dataSeries);
final Compare<AxisSettings> compare = Compare.compare(AxisSettings::getType, xaxis.getType()) if (result.isEmpty()) {
.thenCompare(AxisSettings::getLabel, xaxis.getLabel()); result.add(axis);
}else {
if (!CollectionUtils.contains(result, compare)) { final Compare<AxisSettings> compare = Compare.compare(AxisSettings::getType, axis.getType());
result.add(xaxis); long count = CollectionUtils.count(result, compare);
if (count == 0) {
Preconditions.checkSmaller(result.size(), 2, "at most two different x-axis are supported");
final GnuplotAxis mirrorAxis = axis.getAxis().mirrorAxis();
axis.setAxis(mirrorAxis);
handler.setxAxis(mirrorAxis);
result.add(axis);
} else if (count == 1){
// already has an axis of this type
// TODO merge axis definitions and use the greater values for: range, ticsIncrement
}
} }
} }
return result; return result;
@@ -44,13 +56,23 @@ public class AggregateHandlerCollection {
public List<AxisSettings> getYAxisDefinitions(GnuplotSettings settings, Collection<DataSeries> dataSeries) { public List<AxisSettings> getYAxisDefinitions(GnuplotSettings settings, Collection<DataSeries> dataSeries) {
List<AxisSettings> result = new ArrayList<>(); List<AxisSettings> result = new ArrayList<>();
for (AggregateHandler handler : aggregateHandlers) { for (AggregateHandler handler : aggregateHandlers) {
AxisSettings axis = handler.createYAxisSettings(settings, dataSeries); final AxisSettings axis = handler.createYAxisSettings(settings, dataSeries);
final Compare<AxisSettings> compare = Compare.compare(AxisSettings::getType, axis.getType()) if (result.isEmpty()) {
.thenCompare(AxisSettings::getLabel, axis.getLabel());
if (!CollectionUtils.contains(result, compare)) {
result.add(axis); result.add(axis);
}else {
final Compare<AxisSettings> compare = Compare.compare(AxisSettings::getType, axis.getType());
long count = CollectionUtils.count(result, compare);
if (count == 0) {
Preconditions.checkSmaller(result.size(), 2, "at most two different y-axis are supported");
final GnuplotAxis mirrorAxis = axis.getAxis().mirrorAxis();
axis.setAxis(mirrorAxis);
handler.setyAxis(mirrorAxis);
result.add(axis);
} else if (count == 1){
// already has an axis of this type
// TODO merge axis definitions and use the greater values for: range, ticsIncrement
}
} }
} }
return result; return result;

View File

@@ -12,7 +12,7 @@ import org.lucares.recommind.logs.LineStyle;
import org.lucares.recommind.logs.AxisSettings; import org.lucares.recommind.logs.AxisSettings;
import org.lucares.recommind.logs.AxisSettings.Type; import org.lucares.recommind.logs.AxisSettings.Type;
public class CumulativeDistributionHandler implements AggregateHandler { public class CumulativeDistributionHandler extends AggregateHandler {
@Override @Override
public CustomAggregator createCustomAggregator(final Path tmpDir, PlotSettings plotSettings, public CustomAggregator createCustomAggregator(final Path tmpDir, PlotSettings plotSettings,
@@ -33,7 +33,7 @@ public class CumulativeDistributionHandler implements AggregateHandler {
AxisSettings result = new AxisSettings(); AxisSettings result = new AxisSettings();
result.setLabel("Cumulative Distribution"); result.setLabel("Cumulative Distribution");
result.setType(Type.Number); result.setType(Type.Number);
result.setAxis(GnuplotAxis.X2); // TODO determine automatically result.setAxis(GnuplotAxis.X1); // TODO determine automatically
result.setFormat("%.0f%%"); result.setFormat("%.0f%%");
result.setTicIncrement(computeTicIncrement(settings)); result.setTicIncrement(computeTicIncrement(settings));
result.setFrom("0"); result.setFrom("0");
@@ -55,9 +55,10 @@ public class CumulativeDistributionHandler implements AggregateHandler {
@Override @Override
public void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle, public void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle,
Optional<String> title) { Optional<String> title) {
appendfln(result, "'%s' using 1:2 %s with lines axes x2y1 lw 2 %s, \\", // appendfln(result, "'%s' using 1:2 %s with lines axes %s lw 2 %s, \\", //
aggregatedData.getDataFile().getAbsolutePath(), // aggregatedData.getDataFile().getAbsolutePath(), //
gnuplotTitle(title), // gnuplotTitle(title), //
gnuplotXYAxis(), //
lineStyle.darker()// lineStyle.darker()//
); );
} }

View File

@@ -9,17 +9,20 @@ import org.lucares.recommind.logs.GnuplotAxis;
import org.lucares.recommind.logs.GnuplotSettings; import org.lucares.recommind.logs.GnuplotSettings;
import org.lucares.recommind.logs.LineStyle; import org.lucares.recommind.logs.LineStyle;
import org.lucares.recommind.logs.AxisSettings; import org.lucares.recommind.logs.AxisSettings;
import org.lucares.recommind.logs.AxisSettings.Type;
import org.lucares.recommind.logs.AxisTime; import org.lucares.recommind.logs.AxisTime;
import org.lucares.recommind.logs.DataSeries; import org.lucares.recommind.logs.DataSeries;
public class ParallelRequestsAggregate implements AggregateHandler { public class ParallelRequestsAggregate extends AggregateHandler {
@Override @Override
public AxisSettings createYAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries) { public AxisSettings createYAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries) {
final AxisSettings result = new AxisSettings(); final AxisSettings result = new AxisSettings();
result.setLabel("Parallel Requests"); result.setLabel("Parallel Requests");
result.setAxis(GnuplotAxis.Y2); result.setType(Type.Number);
result.setAxis(GnuplotAxis.Y1);
result.setTicsEnabled(true); result.setTicsEnabled(true);
result.setFrom("0");
return result; return result;
} }
@@ -31,9 +34,10 @@ public class ParallelRequestsAggregate implements AggregateHandler {
@Override @Override
public void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle, public void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle,
Optional<String> title) { Optional<String> title) {
appendfln(result, "'%s' using 1:2 %s with filledcurve axes x1y2 lw 1 %s, \\", // appendfln(result, "'%s' using 1:2 %s with filledcurve axes %s lw 1 %s, \\", //
aggregatedData.getDataFile().getAbsolutePath(), // aggregatedData.getDataFile().getAbsolutePath(), //
gnuplotTitle(title), // gnuplotTitle(title), //
gnuplotXYAxis(), //
lineStyle.brighter().asGnuplotLineStyle()// lineStyle.brighter().asGnuplotLineStyle()//
); );
} }

View File

@@ -11,7 +11,7 @@ import org.lucares.recommind.logs.GnuplotLineType;
import org.lucares.recommind.logs.GnuplotSettings; import org.lucares.recommind.logs.GnuplotSettings;
import org.lucares.recommind.logs.LineStyle; import org.lucares.recommind.logs.LineStyle;
public class ScatterAggregateHandler implements AggregateHandler { public class ScatterAggregateHandler extends AggregateHandler {
@Override @Override
public AxisSettings createYAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries) { public AxisSettings createYAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries) {
@@ -27,10 +27,11 @@ public class ScatterAggregateHandler implements AggregateHandler {
public void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle, public void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle,
Optional<String> title) { Optional<String> title) {
appendfln(result, "'%s' using 1:2 %s with %s %s, \\", // appendfln(result, "'%s' using 1:2 %s with %s axes %s %s, \\", //
aggregatedData.getDataFile(), // aggregatedData.getDataFile(), //
gnuplotTitle(title), // gnuplotTitle(title), //
GnuplotLineType.Points, // GnuplotLineType.Points, //
gnuplotXYAxis(),//
lineStyle// lineStyle//
); );
} }

View File

@@ -10,7 +10,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
public class AxisSettings { public class AxisSettings {
public enum Type { public enum Type {
Number, Time Number, Time, Duration
} }
private String format = ""; private String format = "";
@@ -179,7 +179,5 @@ public class AxisSettings {
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
return e.getMessage(); return e.getMessage();
} }
} }
} }

View File

@@ -40,6 +40,7 @@ public class AxisTime {
public static AxisSettings createYAxis(GnuplotSettings settings, Collection<DataSeries> dataSeries) { public static AxisSettings createYAxis(GnuplotSettings settings, Collection<DataSeries> dataSeries) {
AxisSettings result = new AxisSettings(); AxisSettings result = new AxisSettings();
result.setLabel("Duration"); result.setLabel("Duration");
result.setType(Type.Duration);
result.setAxis(GnuplotAxis.Y1); result.setAxis(GnuplotAxis.Y1);
result.setTicsEnabled(true); result.setTicsEnabled(true);

View File

@@ -1,28 +1,43 @@
package org.lucares.recommind.logs; package org.lucares.recommind.logs;
public enum GnuplotAxis { public enum GnuplotAxis {
X1("x", ""), X1("x", "x1"),
X2("x2", "x2"),
Y1("y", "y"),
Y2("y2", "y2");
private String axis;
private String axisNameForTics;
private GnuplotAxis(String axis, String axisNameForTics) { X2("x2", "x2"),
this.axis = axis;
this.axisNameForTics = axisNameForTics; Y1("y", "y1"),
}
Y2("y2", "y2");
@Override
public String toString() { private String axis;
return axis; private String axisNameForPlots;
}
private GnuplotAxis(String axis, String axisNameForPlots) {
public String getAxisNameForTics() { this.axis = axis;
return axisNameForTics; this.axisNameForPlots = axisNameForPlots;
}
@Override
public String toString() {
return axis;
}
public String getAxisNameForPlots() {
return axisNameForPlots;
}
public GnuplotAxis mirrorAxis() {
switch (this) {
case X1:
return X2;
case X2:
return X1;
case Y1:
return Y2;
case Y2:
return Y1;
default:
throw new IllegalArgumentException("Unexpected value: " + this);
} }
}
} }

View File

@@ -117,6 +117,17 @@ public class CollectionUtils {
} }
return false; return false;
} }
public static <T> long count(Collection<T> collection, final Compare<T> compare) {
long count = 0;
for (T t : collection) {
boolean found = compare.test(t);
if (found ) {
count++;
}
}
return count;
}
public static <V, T extends Collection<V>> T removeAll(final T collection, final T remove, public static <V, T extends Collection<V>> T removeAll(final T collection, final T remove,
final Supplier<T> generator) { final Supplier<T> generator) {