From f3556b6909949c452e12aa93f7baab4116efe3be Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Wed, 3 Apr 2024 16:14:36 +0200 Subject: [PATCH] custom ticks for no unit y-axis --- .../lucares/recommind/logs/YAxisTicks.java | 81 ++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/pdb-plotting/src/main/java/org/lucares/recommind/logs/YAxisTicks.java b/pdb-plotting/src/main/java/org/lucares/recommind/logs/YAxisTicks.java index fef41c2..e092b39 100644 --- a/pdb-plotting/src/main/java/org/lucares/recommind/logs/YAxisTicks.java +++ b/pdb-plotting/src/main/java/org/lucares/recommind/logs/YAxisTicks.java @@ -60,6 +60,7 @@ class YAxisTicks { } else { switch (yAxisDefinition.getAxisScale()) { case LINEAR: + result = computeLinearYTicksNoUnit(height, yRangeMin, yRangeMax); break; case LOG10: result = computeLog10YTicksNoUnit(height, yRangeMin, yRangeMax); @@ -206,25 +207,103 @@ class YAxisTicks { final List ticsLabels = Arrays.asList(// "\"1\" 1", // + "\"2\" 2", // + "\"5\" 5", // "\"10\" 10", // + "\"20\" 20", // + "\"50\" 50", // "\"100\" 100", // + "\"200\" 200", // + "\"500\" 500", // "\"1000\" 1000", // + "\"2000\" 2000", // + "\"5000\" 5000", // "\"10k\" 10000", // + "\"20k\" 20000", // + "\"50k\" 50000", // "\"100k\" 100000", // + "\"200k\" 200000", // + "\"500k\" 500000", // "\"1m\" 1000000", // + "\"2m\" 2000000", // + "\"5m\" 5000000", // "\"10m\" 10000000", // + "\"20m\" 20000000", // + "\"50m\" 50000000", // "\"100m\" 100000000", // + "\"200m\" 200000000", // + "\"500m\" 500000000", // "\"1b\" 1000000000.0", // + "\"2b\" 2000000000.0", // + "\"5b\" 5000000000.0", // "\"10b\" 10000000000.0", // + "\"20b\" 20000000000.0", // + "\"50b\" 50000000000.0", // "\"100b\" 100000000000.0", // + "\"200b\" 200000000000.0", // + "\"500b\" 500000000000.0", // "\"1t\" 1000000000000.0", // + "\"2t\" 2000000000000.0", // + "\"5t\" 5000000000000.0", // "\"10t\" 10000000000000.0", // - "\"100t\" 100000000000000.0" // + "\"20t\" 20000000000000.0", // + "\"50t\" 50000000000000.0", // + "\"100t\" 100000000000000.0", // + "\"200t\" 2000000000000000.0", // + "\"500t\" 5000000000000000.0", // + "\"1q\" 10000000000000000.0", // + "\"2q\" 20000000000000000.0", // + "\"5q\" 50000000000000000.0" // ); return ticsLabels; } + private static List computeLinearYTicksNoUnit(final long height, final long yRangeMinInMs, + final long yRangeMaxInMs) { + final long plotHeight = height - GnuplotSettings.GNUPLOT_TOP_BOTTOM_MARGIN; + final long maxLabels = plotHeight / (GnuplotSettings.TICKS_FONT_SIZE * 2); + + final long range = yRangeMaxInMs - yRangeMinInMs; + final long rangePerLabel = roundToNextLinearNoUnitStep(range / maxLabels); + + final List ticsLabels = new ArrayList<>(); + for (long i = yRangeMinInMs; i <= yRangeMaxInMs; i += rangePerLabel) { + ticsLabels.add("\"" + valueToTic(i, rangePerLabel) + "\" " + i); + } + + return ticsLabels; + } + + private static String valueToTic(final long val, final double rangePerLabel) { + final List powers = List.of("", "k", "m", "b", "t", "q"); + + int power = 1; + String result = String.format("%d", val); + while (val >= Math.pow(1000, power) && power < powers.size()) { + result = String.format("%.3f", val / Math.pow(1000, power)); + result = result.replaceAll("\\.?0*$", ""); + result = result + powers.get(power); + power = power + 1; + } + return result; + } + + private static long roundToNextLinearNoUnitStep(final long stepSize) { + final List steps = Arrays.asList(1L, 5L, 10L, 20L, 25L, 50L, 100L, 200L, 250L, 500L, 1000L, 2000L, 2500L, + 5000L, 10_000L, 20_000L, 25_000L, 50_000L, 100_000L, 200_000L, 250_000L, 500_000L, 1_000_000L, + 2_000_000L, 2_500_000L, 5_000_000L, 10_000_000L, 20_000_000L, 25_000_000L, 100_000_000L, 200_000_000L, + 250_000_000L, 500_000_000L, 1_000_000_000L, 2_000_000_000L, 2_500_000_000L, 5_000_000_000L); + + for (final Long step : steps) { + if (stepSize < step) { + return step; + } + } + + return stepSize; + } + private static long roundToLinearLabelSteps(final long msPerLabel) { final List 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),