cleanup
This commit is contained in:
@@ -26,10 +26,6 @@ public interface AggregateHandler {
|
|||||||
return title.isPresent() ? "title '"+title.get()+"'": "notitle";
|
return title.isPresent() ? "title '"+title.get()+"'": "notitle";
|
||||||
}
|
}
|
||||||
|
|
||||||
// void addPlotsBeforeScatter(StringBuilder result, Collection<DataSeries> dataSeries);
|
|
||||||
//
|
|
||||||
// void addPlotsAfterScatter(StringBuilder result, Collection<DataSeries> dataSeries);
|
|
||||||
|
|
||||||
void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle, Optional<String> title);
|
void addPlot(StringBuilder result, AggregatedData aggregatedData, LineStyle lineStyle, Optional<String> title);
|
||||||
|
|
||||||
CustomAggregator createCustomAggregator(Path tmpDir, PlotSettings plotSettings, long fromEpochMilli, long toEpochMilli);
|
CustomAggregator createCustomAggregator(Path tmpDir, PlotSettings plotSettings, long fromEpochMilli, long toEpochMilli);
|
||||||
|
|||||||
@@ -1,22 +1,12 @@
|
|||||||
package org.lucares.recommind.logs;
|
package org.lucares.recommind.logs;
|
||||||
|
|
||||||
import static java.util.concurrent.TimeUnit.DAYS;
|
|
||||||
import static java.util.concurrent.TimeUnit.HOURS;
|
|
||||||
import static java.util.concurrent.TimeUnit.MINUTES;
|
|
||||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.lucares.pdb.plot.api.AxisScale;
|
import org.lucares.pdb.plot.api.AxisScale;
|
||||||
|
|
||||||
public class GnuplotFileGenerator {
|
public class GnuplotFileGenerator {
|
||||||
|
|
||||||
private static final int KEY_FONT_SIZE = 10;
|
private static final int KEY_FONT_SIZE = 10;
|
||||||
private static final int TICKS_FONT_SIZE = 12;
|
|
||||||
|
|
||||||
public String generate(final GnuplotSettings settings, final Collection<DataSeries> dataSeries) {
|
public String generate(final GnuplotSettings settings, final Collection<DataSeries> dataSeries) {
|
||||||
|
|
||||||
@@ -60,14 +50,6 @@ public class GnuplotFileGenerator {
|
|||||||
appendfln(result, "set grid");
|
appendfln(result, "set grid");
|
||||||
appendfln(result, "set output \"%s\"", settings.getOutput().toAbsolutePath().toString().replace("\\", "/"));
|
appendfln(result, "set output \"%s\"", settings.getOutput().toAbsolutePath().toString().replace("\\", "/"));
|
||||||
|
|
||||||
// TODO remove marker lines?
|
|
||||||
// marker lines that show which area will be zoomed
|
|
||||||
appendfln(result, "set arrow from graph 0.25,0 rto graph 0,1 lc rgb \"#EEEEEE\" nohead");
|
|
||||||
appendfln(result, "set arrow from graph 0.75,0 rto graph 0,1 lc rgb \"#EEEEEE\" nohead");
|
|
||||||
|
|
||||||
// marker line for the 60 second threshold
|
|
||||||
appendfln(result, "set arrow from graph 0, first 60000 rto graph 1,0 lc rgb \"#EEEEEE\" nohead");
|
|
||||||
|
|
||||||
if (settings.isKeyOutside()) {
|
if (settings.isKeyOutside()) {
|
||||||
appendfln(result, "set key outside");
|
appendfln(result, "set key outside");
|
||||||
}
|
}
|
||||||
@@ -94,11 +76,11 @@ public class GnuplotFileGenerator {
|
|||||||
appendln(result, "set tmargin 3"); // margin 3 -> 57px - marker (1)
|
appendln(result, "set tmargin 3"); // margin 3 -> 57px - marker (1)
|
||||||
appendln(result, "set bmargin 4"); // margin 4 -> 76
|
appendln(result, "set bmargin 4"); // margin 4 -> 76
|
||||||
|
|
||||||
appendfln(result, "set tics font \",%d\"", TICKS_FONT_SIZE);
|
appendfln(result, "set tics font \",%d\"", YAxisTicks.TICKS_FONT_SIZE);
|
||||||
appendln(result, computeYTicks(settings, dataSeries));
|
appendln(result, YAxisTicks.computeYTicks(settings, dataSeries));
|
||||||
} else {
|
} else {
|
||||||
appendfln(result, "set tics font \",%d\"", TICKS_FONT_SIZE);
|
appendfln(result, "set tics font \",%d\"", YAxisTicks.TICKS_FONT_SIZE);
|
||||||
appendln(result, computeYTicks(settings, dataSeries));
|
appendln(result, YAxisTicks.computeYTicks(settings, dataSeries));
|
||||||
}
|
}
|
||||||
|
|
||||||
appendf(result, "plot ");
|
appendf(result, "plot ");
|
||||||
@@ -124,152 +106,5 @@ public class GnuplotFileGenerator {
|
|||||||
builder.append(String.format(format, args));
|
builder.append(String.format(format, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String computeYTicks(final GnuplotSettings settings, final Collection<DataSeries> dataSeries) {
|
|
||||||
String result = "";
|
|
||||||
|
|
||||||
final long yRangeMax;
|
|
||||||
final long yRangeMin;
|
|
||||||
if (settings.hasYRange()) {
|
|
||||||
yRangeMax = settings.getYRangeMax();
|
|
||||||
yRangeMin = settings.getYRangeMin();
|
|
||||||
} else {
|
|
||||||
yRangeMax = DataSeries.maxValue(dataSeries);
|
|
||||||
yRangeMin = 0;
|
|
||||||
}
|
|
||||||
final int height = settings.getHeight();
|
|
||||||
|
|
||||||
switch (settings.getYAxisScale()) {
|
|
||||||
case LINEAR:
|
|
||||||
result = computeLinearYTicks(height, yRangeMin, yRangeMax);
|
|
||||||
break;
|
|
||||||
case LOG10:
|
|
||||||
result = computeLog10YTicks(height, yRangeMin, yRangeMax);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// use the default
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String computeLog10YTicks(final int height, final long yRangeMin, final long yRangeMax) {
|
|
||||||
final StringBuilder result = new StringBuilder();
|
|
||||||
appendfln(result, "set ylabel \"%s\"", "Duration");
|
|
||||||
|
|
||||||
final List<String> ticsLabels = Arrays.asList(//
|
|
||||||
"\"1ms\" 1", //
|
|
||||||
"\"2ms\" 2", //
|
|
||||||
"\"5ms\" 5", //
|
|
||||||
"\"10ms\" 10", //
|
|
||||||
"\"20ms\" 20", //
|
|
||||||
"\"50ms\" 50", //
|
|
||||||
"\"100ms\" 100", //
|
|
||||||
"\"200ms\" 200", //
|
|
||||||
"\"500ms\" 500", //
|
|
||||||
"\"1s\" 1000", //
|
|
||||||
"\"2s\" 2000", //
|
|
||||||
"\"5s\" 5000", //
|
|
||||||
"\"10s\" 10000", //
|
|
||||||
"\"30s\" 30000", //
|
|
||||||
"\"1m\" 60000", //
|
|
||||||
"\"2m\" 120000", //
|
|
||||||
"\"5m\" 300000", //
|
|
||||||
"\"10m\" 600000", //
|
|
||||||
"\"30m\" 1800000", //
|
|
||||||
"\"1h\" 3600000", //
|
|
||||||
"\"2h\" 7200000", //
|
|
||||||
"\"4h\" 14400000", //
|
|
||||||
"\"8h\" 28800000", //
|
|
||||||
"\"16h\" 57600000", //
|
|
||||||
"\"1d\" 86400000", //
|
|
||||||
"\"2d\" 172800000", //
|
|
||||||
"\"1 week\" 604800000", //
|
|
||||||
"\"2 week\" 1209600000.0", //
|
|
||||||
"\"4 week\" 2419200000.0" //
|
|
||||||
);
|
|
||||||
|
|
||||||
result.append("set ytics (");
|
|
||||||
result.append(String.join(", ", ticsLabels));
|
|
||||||
result.append(")\n");
|
|
||||||
|
|
||||||
return result.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String computeLinearYTicks(final long height, final long yRangeMin, final long yRangeMax) {
|
|
||||||
final StringBuilder result = new StringBuilder();
|
|
||||||
appendfln(result, "set ylabel \"%s\"", "Duration");
|
|
||||||
|
|
||||||
final long plotHeight = height - GnuplotSettings.GNUPLOT_TOP_BOTTOM_MARGIN; // sum of top/bottom margin, see
|
|
||||||
// marker (1)
|
|
||||||
final long maxLabels = plotHeight / (TICKS_FONT_SIZE * 5);
|
|
||||||
|
|
||||||
final long range = yRangeMax - yRangeMin;
|
|
||||||
final long msPerLabel = roundToLinearLabelSteps(range / maxLabels);
|
|
||||||
|
|
||||||
final List<String> ticsLabels = new ArrayList<>();
|
|
||||||
for (long i = yRangeMin; i <= yRangeMax; i += msPerLabel) {
|
|
||||||
ticsLabels.add("\"" + msToTic(i, msPerLabel) + "\" " + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
result.append("set ytics (");
|
|
||||||
result.append(String.join(", ", ticsLabels));
|
|
||||||
result.append(")\n");
|
|
||||||
return result.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private long roundToLinearLabelSteps(final long msPerLabel) {
|
|
||||||
final List<Long> steps = Arrays.asList(2L, 5L, 10L, 20L, 50L, 100L, 200L, 500L, 1000L, 2000L, 5000L, 10_000L,
|
|
||||||
20_000L, MINUTES.toMillis(1), MINUTES.toMillis(2), MINUTES.toMillis(5), MINUTES.toMillis(10),
|
|
||||||
MINUTES.toMillis(15), MINUTES.toMillis(30), HOURS.toMillis(1), HOURS.toMillis(2), HOURS.toMillis(5),
|
|
||||||
HOURS.toMillis(10), HOURS.toMillis(12), DAYS.toMillis(1), DAYS.toMillis(2), DAYS.toMillis(5),
|
|
||||||
DAYS.toMillis(7));
|
|
||||||
|
|
||||||
for (final Long step : steps) {
|
|
||||||
if (msPerLabel < step) {
|
|
||||||
return step;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return msPerLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String msToTic(final long ms, final double msPerLabel) {
|
|
||||||
|
|
||||||
if (ms < 1000) {
|
|
||||||
return ms + "ms";
|
|
||||||
} else if (ms < MINUTES.toMillis(1)) {
|
|
||||||
if (msPerLabel % 1000 == 0) {
|
|
||||||
return String.format("%ds", ms / 1_000);
|
|
||||||
} else {
|
|
||||||
return String.format("%.1fs", ms / 1_000.0);
|
|
||||||
}
|
|
||||||
} else if (ms < TimeUnit.HOURS.toMillis(1)) {
|
|
||||||
|
|
||||||
final long sec = (ms % MINUTES.toMillis(1)) / SECONDS.toMillis(1);
|
|
||||||
final long min = ms / MINUTES.toMillis(1);
|
|
||||||
if (msPerLabel % MINUTES.toMillis(1) == 0) {
|
|
||||||
return min + "m ";
|
|
||||||
} else {
|
|
||||||
return min + "m " + sec + "s";
|
|
||||||
}
|
|
||||||
} else if (ms < DAYS.toMillis(1)) {
|
|
||||||
// ms is a multiple of 1 hour, see roundToLinearLabelSteps
|
|
||||||
final long hour = (ms % DAYS.toMillis(1)) / HOURS.toMillis(1);
|
|
||||||
final long min = (ms % HOURS.toMillis(1)) / MINUTES.toMillis(1);
|
|
||||||
final long sec = (ms % MINUTES.toMillis(1)) / SECONDS.toMillis(1);
|
|
||||||
|
|
||||||
if (msPerLabel % MINUTES.toMillis(1) == 0) {
|
|
||||||
return hour + "h " + min + "m ";
|
|
||||||
} else if (msPerLabel % HOURS.toMillis(1) == 0) {
|
|
||||||
return hour + "h ";
|
|
||||||
} else {
|
|
||||||
return hour + "h " + min + "m " + sec + "s";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// ms is a multiple of 1 day, see roundToLinearLabelSteps
|
|
||||||
final long day = ms / DAYS.toMillis(1);
|
|
||||||
final long hour = (ms % DAYS.toMillis(1)) / HOURS.toMillis(1);
|
|
||||||
|
|
||||||
return day + "d " + hour + "h ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,166 @@
|
|||||||
|
package org.lucares.recommind.logs;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.DAYS;
|
||||||
|
import static java.util.concurrent.TimeUnit.HOURS;
|
||||||
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
class YAxisTicks {
|
||||||
|
|
||||||
|
static final int TICKS_FONT_SIZE = 12;
|
||||||
|
|
||||||
|
public static String computeYTicks(final GnuplotSettings settings, final Collection<DataSeries> dataSeries) {
|
||||||
|
String result = "";
|
||||||
|
|
||||||
|
final long yRangeMax;
|
||||||
|
final long yRangeMin;
|
||||||
|
if (settings.hasYRange()) {
|
||||||
|
yRangeMax = settings.getYRangeMax();
|
||||||
|
yRangeMin = settings.getYRangeMin();
|
||||||
|
} else {
|
||||||
|
yRangeMax = DataSeries.maxValue(dataSeries);
|
||||||
|
yRangeMin = 0;
|
||||||
|
}
|
||||||
|
final int height = settings.getHeight();
|
||||||
|
|
||||||
|
switch (settings.getYAxisScale()) {
|
||||||
|
case LINEAR:
|
||||||
|
result = computeLinearYTicks(height, yRangeMin, yRangeMax);
|
||||||
|
break;
|
||||||
|
case LOG10:
|
||||||
|
result = computeLog10YTicks(height, yRangeMin, yRangeMax);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// use the default
|
||||||
|
}
|
||||||
|
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");
|
||||||
|
|
||||||
|
final List<String> ticsLabels = Arrays.asList(//
|
||||||
|
"\"1ms\" 1", //
|
||||||
|
"\"2ms\" 2", //
|
||||||
|
"\"5ms\" 5", //
|
||||||
|
"\"10ms\" 10", //
|
||||||
|
"\"20ms\" 20", //
|
||||||
|
"\"50ms\" 50", //
|
||||||
|
"\"100ms\" 100", //
|
||||||
|
"\"200ms\" 200", //
|
||||||
|
"\"500ms\" 500", //
|
||||||
|
"\"1s\" 1000", //
|
||||||
|
"\"2s\" 2000", //
|
||||||
|
"\"5s\" 5000", //
|
||||||
|
"\"10s\" 10000", //
|
||||||
|
"\"30s\" 30000", //
|
||||||
|
"\"1m\" 60000", //
|
||||||
|
"\"2m\" 120000", //
|
||||||
|
"\"5m\" 300000", //
|
||||||
|
"\"10m\" 600000", //
|
||||||
|
"\"30m\" 1800000", //
|
||||||
|
"\"1h\" 3600000", //
|
||||||
|
"\"2h\" 7200000", //
|
||||||
|
"\"4h\" 14400000", //
|
||||||
|
"\"8h\" 28800000", //
|
||||||
|
"\"16h\" 57600000", //
|
||||||
|
"\"1d\" 86400000", //
|
||||||
|
"\"2d\" 172800000", //
|
||||||
|
"\"1 week\" 604800000", //
|
||||||
|
"\"2 week\" 1209600000.0", //
|
||||||
|
"\"4 week\" 2419200000.0" //
|
||||||
|
);
|
||||||
|
|
||||||
|
result.append("set ytics (");
|
||||||
|
result.append(String.join(", ", ticsLabels));
|
||||||
|
result.append(")\n");
|
||||||
|
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String computeLinearYTicks(final long height, final long yRangeMin, final long yRangeMax) {
|
||||||
|
final StringBuilder result = new StringBuilder();
|
||||||
|
result.append("set ylabel \"Duration\"\n");
|
||||||
|
|
||||||
|
final long plotHeight = height - GnuplotSettings.GNUPLOT_TOP_BOTTOM_MARGIN; // sum of top/bottom margin, see
|
||||||
|
// marker (1)
|
||||||
|
final long maxLabels = plotHeight / (TICKS_FONT_SIZE * 5);
|
||||||
|
|
||||||
|
final long range = yRangeMax - yRangeMin;
|
||||||
|
final long msPerLabel = roundToLinearLabelSteps(range / maxLabels);
|
||||||
|
|
||||||
|
final List<String> ticsLabels = new ArrayList<>();
|
||||||
|
for (long i = yRangeMin; i <= yRangeMax; i += msPerLabel) {
|
||||||
|
ticsLabels.add("\"" + msToTic(i, msPerLabel) + "\" " + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.append("set ytics (");
|
||||||
|
result.append(String.join(", ", ticsLabels));
|
||||||
|
result.append(")\n");
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long roundToLinearLabelSteps(final long msPerLabel) {
|
||||||
|
final List<Long> steps = Arrays.asList(2L, 5L, 10L, 20L, 50L, 100L, 200L, 500L, 1000L, 2000L, 5000L, 10_000L,
|
||||||
|
20_000L, MINUTES.toMillis(1), MINUTES.toMillis(2), MINUTES.toMillis(5), MINUTES.toMillis(10),
|
||||||
|
MINUTES.toMillis(15), MINUTES.toMillis(30), HOURS.toMillis(1), HOURS.toMillis(2), HOURS.toMillis(5),
|
||||||
|
HOURS.toMillis(10), HOURS.toMillis(12), DAYS.toMillis(1), DAYS.toMillis(2), DAYS.toMillis(5),
|
||||||
|
DAYS.toMillis(7));
|
||||||
|
|
||||||
|
for (final Long step : steps) {
|
||||||
|
if (msPerLabel < step) {
|
||||||
|
return step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return msPerLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String msToTic(final long ms, final double msPerLabel) {
|
||||||
|
|
||||||
|
if (ms < 1000) {
|
||||||
|
return ms + "ms";
|
||||||
|
} else if (ms < MINUTES.toMillis(1)) {
|
||||||
|
if (msPerLabel % 1000 == 0) {
|
||||||
|
return String.format("%ds", ms / 1_000);
|
||||||
|
} else {
|
||||||
|
return String.format("%.1fs", ms / 1_000.0);
|
||||||
|
}
|
||||||
|
} else if (ms < TimeUnit.HOURS.toMillis(1)) {
|
||||||
|
|
||||||
|
final long sec = (ms % MINUTES.toMillis(1)) / SECONDS.toMillis(1);
|
||||||
|
final long min = ms / MINUTES.toMillis(1);
|
||||||
|
if (msPerLabel % MINUTES.toMillis(1) == 0) {
|
||||||
|
return min + "m ";
|
||||||
|
} else {
|
||||||
|
return min + "m " + sec + "s";
|
||||||
|
}
|
||||||
|
} else if (ms < DAYS.toMillis(1)) {
|
||||||
|
// ms is a multiple of 1 hour, see roundToLinearLabelSteps
|
||||||
|
final long hour = (ms % DAYS.toMillis(1)) / HOURS.toMillis(1);
|
||||||
|
final long min = (ms % HOURS.toMillis(1)) / MINUTES.toMillis(1);
|
||||||
|
final long sec = (ms % MINUTES.toMillis(1)) / SECONDS.toMillis(1);
|
||||||
|
|
||||||
|
if (msPerLabel % MINUTES.toMillis(1) == 0) {
|
||||||
|
return hour + "h " + min + "m ";
|
||||||
|
} else if (msPerLabel % HOURS.toMillis(1) == 0) {
|
||||||
|
return hour + "h ";
|
||||||
|
} else {
|
||||||
|
return hour + "h " + min + "m " + sec + "s";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// ms is a multiple of 1 day, see roundToLinearLabelSteps
|
||||||
|
final long day = ms / DAYS.toMillis(1);
|
||||||
|
final long hour = (ms % DAYS.toMillis(1)) / HOURS.toMillis(1);
|
||||||
|
|
||||||
|
return day + "d " + hour + "h ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user