make the code that determines which axis to use explicit

In the previous changeset the code that determined
which axis the plots used was implemented as a
side effect of getting the Gnuplot definition of
an axis.
Changed that to an explit update call with simpler
logic.
This commit is contained in:
2019-11-24 09:08:19 +01:00
parent 892d5a6d08
commit e2a33ac6e2
8 changed files with 119 additions and 58 deletions

View File

@@ -5,6 +5,7 @@ import java.util.Collection;
import java.util.Optional; import java.util.Optional;
import org.lucares.recommind.logs.AxisSettings; import org.lucares.recommind.logs.AxisSettings;
import org.lucares.recommind.logs.AxisSettings.Type;
import org.lucares.recommind.logs.DataSeries; import org.lucares.recommind.logs.DataSeries;
import org.lucares.recommind.logs.GnuplotAxis; import org.lucares.recommind.logs.GnuplotAxis;
import org.lucares.recommind.logs.GnuplotSettings; import org.lucares.recommind.logs.GnuplotSettings;
@@ -20,22 +21,31 @@ public abstract class AggregateHandler implements Appender {
return xAxis; return xAxis;
} }
public void setxAxis(GnuplotAxis xAxis) { public void updateAxis(GnuplotAxis axis) {
this.xAxis = xAxis; switch (axis) {
case X1:
case X2:
this.xAxis = axis;
break;
case Y1:
case Y2:
this.yAxis = axis;
break;
default:
throw new IllegalArgumentException("Unexpected value: " + axis);
}
} }
public GnuplotAxis getyAxis() { public GnuplotAxis getyAxis() {
return yAxis; return yAxis;
} }
public void setyAxis(GnuplotAxis yAxis) {
this.yAxis = yAxis;
}
protected String gnuplotXYAxis() { protected String gnuplotXYAxis() {
return xAxis.getAxisNameForPlots()+yAxis.getAxisNameForPlots(); return xAxis.getAxisNameForPlots()+yAxis.getAxisNameForPlots();
} }
abstract Type getAxisType(GnuplotAxis axis);
abstract Aggregate getAggregateType(); abstract Aggregate getAggregateType();
abstract AxisSettings createXAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries); abstract AxisSettings createXAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries);

View File

@@ -3,53 +3,61 @@ package org.lucares.pdb.plot.api;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.lucares.recommind.logs.AxisSettings;
import org.lucares.recommind.logs.AxisSettings.Type;
import org.lucares.recommind.logs.DataSeries; import org.lucares.recommind.logs.DataSeries;
import org.lucares.recommind.logs.GnuplotAxis; 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.utils.CollectionUtils; import org.lucares.utils.CollectionUtils;
import org.lucares.utils.CollectionUtils.Compare;
import org.lucares.utils.Preconditions; 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> PLOTTING_ORDER = Comparator.comparing(AggregateHandler::getAggregateType);
private final List<AggregateHandler> aggregateHandlers = new ArrayList<>(); private final List<AggregateHandler> aggregateHandlers = new ArrayList<>();
public void add(AggregateHandler aggregateHandler) { public void add(AggregateHandler aggregateHandler) {
aggregateHandlers.add(aggregateHandler); aggregateHandlers.add(aggregateHandler);
Collections.sort(aggregateHandlers, COMPARATOR);
} }
public void updateAxisForHandlers() {
updateAxisForHandlers(GnuplotAxis.X1);
updateAxisForHandlers(GnuplotAxis.Y1);
}
private void updateAxisForHandlers(GnuplotAxis axis) {
public List<AxisSettings> getXAxisDefinitions(GnuplotSettings settings, Collection<DataSeries> dataSeries) { final EnumSet<Type> result = EnumSet.noneOf(Type.class);
List<AxisSettings> result = new ArrayList<>();
for (AggregateHandler handler : aggregateHandlers) { for (AggregateHandler handler : aggregateHandlers) {
AxisSettings axis = handler.createXAxisSettings(settings, dataSeries); final Type type = handler.getAxisType(axis);
if (result.isEmpty()) { if (result.isEmpty()) {
result.add(axis); result.add(type);
}else { }else {
final Compare<AxisSettings> compare = Compare.compare(AxisSettings::getType, axis.getType()); final boolean containsType = result.contains(type);
long count = CollectionUtils.count(result, compare); if (containsType) {
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 // already has an axis of this type
// TODO merge axis definitions and use the greater values for: range, ticsIncrement // TODO merge axis definitions and use the greater values for: range, ticsIncrement
} else{
Preconditions.checkSmaller(result.size(), 2, "at most two different axis are supported");
final GnuplotAxis mirrorAxis = axis.mirrorAxis();
handler.updateAxis(mirrorAxis);
result.add(type);
} }
} }
} }
}
public List<AxisSettings> getXAxisDefinitions(GnuplotSettings settings, Collection<DataSeries> dataSeries) {
final List<AxisSettings> result = new ArrayList<>();
for (AggregateHandler handler : aggregateHandlers) {
AxisSettings axis = handler.createXAxisSettings(settings, dataSeries);
result.add(axis);
}
return result; return result;
} }
@@ -57,23 +65,7 @@ public class AggregateHandlerCollection {
List<AxisSettings> result = new ArrayList<>(); List<AxisSettings> result = new ArrayList<>();
for (AggregateHandler handler : aggregateHandlers) { for (AggregateHandler handler : aggregateHandlers) {
final AxisSettings axis = handler.createYAxisSettings(settings, dataSeries); final AxisSettings axis = handler.createYAxisSettings(settings, dataSeries);
result.add(axis);
if (result.isEmpty()) {
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;
} }
@@ -85,7 +77,7 @@ public class AggregateHandlerCollection {
final List<CustomAggregator> aggregators = new ArrayList<>(); final List<CustomAggregator> aggregators = new ArrayList<>();
for (AggregateHandler handler : aggregateHandlers) { for (AggregateHandler handler : aggregateHandlers) {
CustomAggregator aggregator = handler.createCustomAggregator(tmpDir, plotSettings, fromEpochMilli, toEpochMilli); final CustomAggregator aggregator = handler.createCustomAggregator(tmpDir, plotSettings, fromEpochMilli, toEpochMilli);
if (aggregator != null) { if (aggregator != null) {
aggregators.add(aggregator); aggregators.add(aggregator);
} }
@@ -97,7 +89,8 @@ public class AggregateHandlerCollection {
public void addPlots(StringBuilder result, Collection<DataSeries> dataSeries) { public void addPlots(StringBuilder result, Collection<DataSeries> dataSeries) {
boolean first = true; boolean first = true;
for (AggregateHandler handler : aggregateHandlers) { final List<AggregateHandler> handlersInPlottingOrder = CollectionUtils.copySort(aggregateHandlers, PLOTTING_ORDER);
for (AggregateHandler handler : handlersInPlottingOrder) {
for (DataSeries dataSerie : dataSeries) { for (DataSeries dataSerie : dataSeries) {
final Optional<String> title = first ? Optional.of(dataSerie.getTitle()) : Optional.empty(); final Optional<String> title = first ? Optional.of(dataSerie.getTitle()) : Optional.empty();
@@ -109,10 +102,6 @@ public class AggregateHandlerCollection {
} }
first = false; first = false;
} }
} }
} }

View File

@@ -23,17 +23,33 @@ public class CumulativeDistributionHandler extends AggregateHandler {
public CumulativeDistributionHandler() { public CumulativeDistributionHandler() {
} }
@Override
Type getAxisType(GnuplotAxis axis) {
switch (axis) {
case X1:
case X2:
return Type.Percent;
case Y1:
case Y2:
return Type.Duration;
default:
throw new IllegalArgumentException("Unexpected value: " + axis);
}
}
@Override @Override
public AxisSettings createYAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries) { public AxisSettings createYAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries) {
return AxisTime.createYAxis(settings, dataSeries); AxisSettings result = AxisTime.createYAxis(settings, dataSeries);
result.setAxis(getyAxis());
return result;
} }
@Override @Override
public AxisSettings createXAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries) { public AxisSettings createXAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries) {
AxisSettings result = new AxisSettings(); AxisSettings result = new AxisSettings();
result.setLabel("Cumulative Distribution"); result.setLabel("Cumulative Distribution");
result.setType(Type.Number); result.setType(Type.Percent);
result.setAxis(GnuplotAxis.X1); // TODO determine automatically result.setAxis(getxAxis());
result.setFormat("%.0f%%"); result.setFormat("%.0f%%");
result.setTicIncrement(computeTicIncrement(settings)); result.setTicIncrement(computeTicIncrement(settings));
result.setFrom("0"); result.setFrom("0");

View File

@@ -15,12 +15,26 @@ import org.lucares.recommind.logs.DataSeries;
public class ParallelRequestsAggregate extends AggregateHandler { public class ParallelRequestsAggregate extends AggregateHandler {
@Override
Type getAxisType(GnuplotAxis axis) {
switch (axis) {
case X1:
case X2:
return Type.Time;
case Y1:
case Y2:
return Type.Number;
default:
throw new IllegalArgumentException("Unexpected value: " + axis);
}
}
@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.setType(Type.Number); result.setType(Type.Number);
result.setAxis(GnuplotAxis.Y1); result.setAxis(getyAxis());
result.setTicsEnabled(true); result.setTicsEnabled(true);
result.setFrom("0"); result.setFrom("0");
return result; return result;
@@ -28,7 +42,9 @@ public class ParallelRequestsAggregate extends AggregateHandler {
@Override @Override
public AxisSettings createXAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries) { public AxisSettings createXAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries) {
return AxisTime.createXAxis(settings); final AxisSettings result = AxisTime.createXAxis(settings);
result.setAxis(getxAxis());
return result;
} }
@Override @Override

View File

@@ -7,20 +7,40 @@ import java.util.Optional;
import org.lucares.recommind.logs.AxisSettings; import org.lucares.recommind.logs.AxisSettings;
import org.lucares.recommind.logs.AxisTime; import org.lucares.recommind.logs.AxisTime;
import org.lucares.recommind.logs.DataSeries; import org.lucares.recommind.logs.DataSeries;
import org.lucares.recommind.logs.GnuplotAxis;
import org.lucares.recommind.logs.GnuplotLineType; 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;
import org.lucares.recommind.logs.AxisSettings.Type;
public class ScatterAggregateHandler extends AggregateHandler { public class ScatterAggregateHandler extends AggregateHandler {
@Override
Type getAxisType(GnuplotAxis axis) {
switch (axis) {
case X1:
case X2:
return Type.Time;
case Y1:
case Y2:
return Type.Duration;
default:
throw new IllegalArgumentException("Unexpected value: " + axis);
}
}
@Override @Override
public AxisSettings createYAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries) { public AxisSettings createYAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries) {
return AxisTime.createYAxis(settings, dataSeries); final AxisSettings result = AxisTime.createYAxis(settings, dataSeries);
result.setAxis(getyAxis());
return result;
} }
@Override @Override
public AxisSettings createXAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries) { public AxisSettings createXAxisSettings(GnuplotSettings settings, Collection<DataSeries> dataSeries) {
return AxisTime.createXAxis(settings); final AxisSettings result = AxisTime.createXAxis(settings);
result.setAxis(getxAxis());
return result;
} }
@Override @Override

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, Duration Number, Time, Duration, Percent
} }
private String format = ""; private String format = "";

View File

@@ -80,6 +80,8 @@ class PlotSettingsTransformer {
} }
} }
aggregateHandlerCollection.updateAxisForHandlers();
return aggregateHandlerCollection; return aggregateHandlerCollection;
} }
} }

View File

@@ -2,6 +2,8 @@ package org.lucares.utils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -37,6 +39,12 @@ public class CollectionUtils {
} }
public static <T> List<T> copySort(Collection<? extends T> collection, Comparator<T> comparator){
final List<T> result = new ArrayList<T>(collection);
Collections.sort(result, comparator);
return result;
}
public static <T, R extends T> void mapInPlace(final List<T> list, final Function<T, R> mapper) { public static <T, R extends T> void mapInPlace(final List<T> list, final Function<T, R> mapper) {
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
final T value = list.get(i); final T value = list.get(i);