From 718ca3cfc33b722d6383a1b406fca53a75d6ff37 Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Tue, 22 Nov 2016 04:25:04 +0300 Subject: [PATCH] [vcs-log] use weighted average and deviation to calculate recommended graph width Weights are selected as a decreasing arithmetic progression with sum 1. Parameter K allows to fine tune progression decline. Weight of last row is K times of the weight of the first row. --- .../impl/print/PrintElementGeneratorImpl.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/PrintElementGeneratorImpl.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/PrintElementGeneratorImpl.java index d4490841e0a4..da7614ebc04d 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/PrintElementGeneratorImpl.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/PrintElementGeneratorImpl.java @@ -48,7 +48,7 @@ public class PrintElementGeneratorImpl extends AbstractPrintElementGenerator { private static final int CACHE_SIZE = 100; private static final boolean SHOW_ARROW_WHEN_SHOW_LONG_EDGES = true; private static final int SAMPLE_SIZE = 20000; - + private static final double K = 0.1; @NotNull private final SLRUMap> myCache = new SLRUMap<>(CACHE_SIZE, CACHE_SIZE * 2); @NotNull private final EdgesInRowGenerator myEdgesInRowGenerator; @@ -145,14 +145,23 @@ public class PrintElementGeneratorImpl extends AbstractPrintElementGenerator { int width = Math.max(edgesCount + upArrows, newEdgesCount + downArrows); - sum += width; - sumSquares += width * width; + /* + * 0 <= K < 1; weight is an arithmetic progression, starting at 2 / ( n * (k + 1)) ending at k * 2 / ( n * (k + 1)) + * this formula ensures that sum of all weights is 1 + */ + double weight = 2 / (n * (K + 1)) * (1 + (K - 1) * i / (n - 1)); + sum += width * weight; + sumSquares += width * width * weight; edgesCount = newEdgesCount; } - double average = sum / n; - double deviation = Math.sqrt(sumSquares / n - average * average); + /* + weighted variance calculation described here: + http://stackoverflow.com/questions/30383270/how-do-i-calculate-the-standard-deviation-between-weighted-measurements + */ + double average = sum; + double deviation = Math.sqrt(sumSquares - average * average); myRecommendedWidth = (int)Math.round(average + deviation); }