fix overlapping x axis ticks

Gnuplot does not handle long x-axis ticks very good.
It should know how wide the labels are and could adapt
the increment size accordingly, but it doesn't.
Fixed by explicitly defining the increment for x-axis
labels.
This commit is contained in:
2019-11-01 19:13:11 +01:00
parent 7c122b5753
commit c83d0a3e1e
6 changed files with 147 additions and 59 deletions

View File

@@ -24,9 +24,10 @@ public class GnuplotFileGenerator {
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 format x \"%s\"", xAxis.getFormatX());
appendfln(result, "set xlabel \"%s\"", xAxis.getXlabel());
appendfln(result, "set xrange [\"%s\":\"%s\"]", xAxis.getFrom(), xAxis.getTo());
@@ -76,10 +77,10 @@ public class GnuplotFileGenerator {
appendln(result, "set tmargin 3"); // margin 3 -> 57px - marker (1)
appendln(result, "set bmargin 4"); // margin 4 -> 76
appendfln(result, "set tics font \",%d\"", YAxisTicks.TICKS_FONT_SIZE);
appendfln(result, "set tics font \",%d\"", GnuplotSettings.TICKS_FONT_SIZE);
appendln(result, YAxisTicks.computeYTicks(settings, dataSeries));
} else {
appendfln(result, "set tics font \",%d\"", YAxisTicks.TICKS_FONT_SIZE);
appendfln(result, "set tics font \",%d\"", GnuplotSettings.TICKS_FONT_SIZE);
appendln(result, YAxisTicks.computeYTicks(settings, dataSeries));
}

View File

@@ -13,6 +13,7 @@ public class GnuplotSettings {
public final static int GNUPLOT_BOTTOM_MARGIN = 76; // The bottom margin configured for gnuplot
public final static int GNUPLOT_TOP_BOTTOM_MARGIN = GNUPLOT_TOP_MARGIN + GNUPLOT_BOTTOM_MARGIN;
public final static int GNUPLOT_LEFT_RIGHT_MARGIN = GNUPLOT_LEFT_MARGIN+GNUPLOT_RIGHT_MARGIN;
public static final int TICKS_FONT_SIZE = 12;
private String terminal = "png";
private int height = 1200;

View File

@@ -185,6 +185,7 @@ public class Plotter {
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,

View File

@@ -1,76 +1,86 @@
package org.lucares.recommind.logs;
import org.lucares.pdb.api.DateTimeRange;
public class XAxisSettings {
// set xdata time
private boolean xDataTime = true;
// set format for x-axis
private String formatX = "%Y-%m-%d\\n%H:%M:%S";
// set xdata time
private boolean xDataTime = true;
// set xlabel
private String xlabel = "Time";
// set format for x-axis
private String formatX = "%Y-%m-%d\\n%H:%M:%S";
// set xtics rotation in degree
private int rotateXAxisLabel = 0;
// set xlabel
private String xlabel = "Time";
private String from;
private String to;
// set xtics rotation in degree
private int rotateXAxisLabel = 0;
public boolean isxDataTime() {
return xDataTime;
}
private String from;
private String to;
public void setxDataTime(boolean xDataTime) {
this.xDataTime = xDataTime;
}
private DateTimeRange dateTimeRange;
public String getFormatX() {
return formatX;
}
public boolean isxDataTime() {
return xDataTime;
}
public void setFormatX(String formatX) {
this.formatX = formatX;
}
public void setxDataTime(boolean xDataTime) {
this.xDataTime = xDataTime;
}
public String getXlabel() {
return xlabel;
}
public String getFormatX() {
return formatX;
}
public void setXlabel(String xlabel) {
this.xlabel = xlabel;
}
public void setFormatX(String formatX) {
this.formatX = formatX;
}
public int getRotateXAxisLabel() {
return rotateXAxisLabel;
}
public String getXlabel() {
return xlabel;
}
public void setRotateXAxisLabel(int rotateXAxisLabel) {
this.rotateXAxisLabel = rotateXAxisLabel;
}
public void setXlabel(String xlabel) {
this.xlabel = xlabel;
}
public String getFrom() {
return from;
}
public int getRotateXAxisLabel() {
return rotateXAxisLabel;
}
public void setFrom(String from) {
this.from = from;
}
public void setRotateXAxisLabel(int rotateXAxisLabel) {
this.rotateXAxisLabel = rotateXAxisLabel;
}
public String getTo() {
return to;
}
public String getFrom() {
return from;
}
public void setTo(String to) {
this.to = to;
}
public void setFrom(String from) {
this.from = from;
}
@Override
public String toString() {
return "XAxisSettings [xDataTime=" + xDataTime + ", formatX=" + formatX
+ ", xlabel=" + xlabel + ", rotateXAxisLabel="
+ rotateXAxisLabel + ", from=" + from + ", to=" + to + "]";
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public void setDateTimeRange(DateTimeRange dateTimeRange) {
this.dateTimeRange = dateTimeRange;
}
public DateTimeRange getDateTimeRange() {
return dateTimeRange;
}
@Override
public String toString() {
return "XAxisSettings [xDataTime=" + xDataTime + ", formatX=" + formatX + ", xlabel=" + xlabel
+ ", rotateXAxisLabel=" + rotateXAxisLabel + ", from=" + from + ", to=" + to + ", dateTimeRange="+dateTimeRange+"]";
}
}

View File

@@ -0,0 +1,76 @@
package org.lucares.recommind.logs;
import java.util.concurrent.TimeUnit;
import org.lucares.collections.LongList;
import org.lucares.pdb.api.DateTimeRange;
public class XAxisTimeTicks {
public static String computeXTimeIncrements(GnuplotSettings settings) {
DateTimeRange dateTimeRange = settings.getxAxisSettings().getDateTimeRange();
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;
final long maxLabels = widthInPx / (GnuplotSettings.TICKS_FONT_SIZE * 8);
final long tickIncrement = roundToTickIncrement(rangeInMs / maxLabels);
return "set xtics "+ tickIncrement/1000.0;
}
private static long roundToTickIncrement(long milliseconds) {
LongList increments = LongList.of(
100,
200,
500,
TimeUnit.SECONDS.toMillis(1),
TimeUnit.SECONDS.toMillis(2),
TimeUnit.SECONDS.toMillis(5),
TimeUnit.SECONDS.toMillis(10),
TimeUnit.SECONDS.toMillis(15),
TimeUnit.SECONDS.toMillis(30),
TimeUnit.MINUTES.toMillis(1),
TimeUnit.MINUTES.toMillis(2),
TimeUnit.MINUTES.toMillis(5),
TimeUnit.MINUTES.toMillis(10),
TimeUnit.MINUTES.toMillis(15),
TimeUnit.MINUTES.toMillis(30),
TimeUnit.HOURS.toMillis(1),
TimeUnit.HOURS.toMillis(2),
TimeUnit.HOURS.toMillis(3),
TimeUnit.HOURS.toMillis(6),
TimeUnit.HOURS.toMillis(12),
TimeUnit.HOURS.toMillis(18),
TimeUnit.DAYS.toMillis(1),
TimeUnit.DAYS.toMillis(2),
TimeUnit.DAYS.toMillis(3),
TimeUnit.DAYS.toMillis(4),
TimeUnit.DAYS.toMillis(5),
TimeUnit.DAYS.toMillis(6),
TimeUnit.DAYS.toMillis(7),
TimeUnit.DAYS.toMillis(14),
TimeUnit.DAYS.toMillis(30),
TimeUnit.DAYS.toMillis(90),
TimeUnit.DAYS.toMillis(180),
TimeUnit.DAYS.toMillis(365),
TimeUnit.DAYS.toMillis(365*2),
TimeUnit.DAYS.toMillis(365*5),
TimeUnit.DAYS.toMillis(365*10),
TimeUnit.DAYS.toMillis(365*20)
);
for ( int i = 0; i < increments.size(); i++) {
if (increments.get(i) > milliseconds) {
return increments.get(i);
}
}
return TimeUnit.DAYS.toMillis(365*10);
}
}

View File

@@ -13,7 +13,6 @@ 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 = "";
@@ -91,7 +90,7 @@ private static String computeLinearYTicks(final long height, final long yRangeMi
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 maxLabels = plotHeight / (GnuplotSettings.TICKS_FONT_SIZE * 5);
final long range = yRangeMax - yRangeMin;
final long msPerLabel = roundToLinearLabelSteps(range / maxLabels);