redesign the help statistics plot - #560
Neil-Tomar wants to merge 2 commits into
Conversation
| import java.util.LinkedHashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.*; |
There was a problem hiding this comment.
Please avoid the wildcard import.
There was a problem hiding this comment.
Note: The wildcard import is still present.
|
|
||
| public static boolean compareImage(BufferedImage img1, BufferedImage img2) { | ||
| if (img1 == null || img2 == null) { | ||
| return false; |
There was a problem hiding this comment.
Instead of just returning boolean and asserting it being true, please use proper assertions when they happen, e.g. assertNonNull(actual) and assertEquals(expected.getWidth(), actual.getWidth(), "image width does not match")
|
When I built it with native-image, it failed with the following exception: |
|
Performance test (single shot, running only the plotting logic, including startup time, with native-image, repeated 6 times)
It seems like at least with your test case, your change doesn't seem to make too much of a difference in terms of time. |
| * @param subtitleText the subtitle of plot | ||
| */ | ||
| public Plotter(List<Pair<String, Bar>> entries, String title, String subtitle) { | ||
| public Plotter(List<Pair<String, Bar>> entries, String titleText, String subtitleText) { |
There was a problem hiding this comment.
Is this constructor needed (are there any calls that shouldn't set darkMode to anything)? If yes, is there a reason this doesn't just call the other constructor using this(entries, titleText, subtitleText, false);?
| .mapToDouble(Bar::sum) | ||
| .max().orElse(0); | ||
| private void drawGraph(Graphics2D graphics2D) { | ||
| double maxValue = entries.stream().map(Pair::second).mapToDouble(Bar::sum).max().orElse(0); |
There was a problem hiding this comment.
Is there a reason you reduced this to a single line?
| private static final int AXIS_LABEL_MARGIN_LEFT = (int) (WIDTH * 0.045); // 4.5% | ||
| private static final int GRAPH_MARGIN_LEFT = (int) (WIDTH * 0.05); // 5% | ||
| private static final int GRAPH_MARGIN_RIGHT = (int) (WIDTH * 0.02); // 2% | ||
| private static final int AXIS_LABEL_MARGIN_BOTTOM = (int) (HEIGHT * 0.043); // 4.3% |
There was a problem hiding this comment.
As far as I can see, this is the amount of space between the bottom of the plot and the top of the label. Is this correct? I think there's a risk of confusing this something else (e.g. GRAPH_MARGIN_BOTTOM is the space between the very bottom of the image and the bottom of the graph as far as I can see which is the more obvious interpretation) so a comment saying this wouldn't hurt IMO.
There was a problem hiding this comment.
Words are getting kind of confusing.

I believe AXIS_LABEL_MARGIN_BOTTOM is the space between red lines. but I just changed some things which will be in next commit so now bottom red line is shifted to middle of the text like in image below.

I know this is more confusing because it is supposed to represent space between. If you want, I can add extra value like FontHeight/2 at drawStringCentered(graphics2D, label, centerX, GRAPH_MARGIN_TOP + GRAPH_HEIGHT + AXIS_LABEL_MARGIN_BOTTOM);.
let me know on what you think.
| private static final int GRID_LINES = 5; | ||
| private static final int BAR_LABEL_MARGIN = 34; | ||
| private static final int BAR_LABEL_HEIGHT = 42; | ||
| private static final int BAR_LABEL_BOTTOM_MARGIN = 65; |
There was a problem hiding this comment.
Similar to AXIS_LABEL_MARGIN_BOTTOM, I think a comment explaining what exactly this is wouldn't hurt either. From what I can see, this is the space between the bottom of the axis label and the top of the bar (which I think is intuitive but explaining it in a comment doesn't hurt either)?
There was a problem hiding this comment.
BAR_LABEL_BOTTOM_MARGIN represents the space between red lines in following image.

I know this is confusing because once again this is supposed to represents space between Bar Label and Top Bar. The issue is caused because y-axis value increases when moving down and I got confused because of that. But the issue is fixed and will be committed in next change.
| double value = element.second(); | ||
| int segmentHeight = (int) (height * (value / axisMax)); | ||
| if (segmentHeight <= 0) continue; | ||
| Font valueFont = ImageGenerationUtils.getResourceFont("assets/fonts/Uni-Sans-Heavy.ttf", VALUE_SIZE).orElseThrow(); |
There was a problem hiding this comment.
I think you should only create the font once (per plot) and not for every label. You could move this to a field (and initialize it in the constructor or similar). I don't have a particular preference for whether or not static variables should be used but it may be a good idea to do the same for all fonts in the Plotter class.
| graphics2D.setColor(barLabelColor); | ||
| graphics2D.fillRoundRect(centerX - barLabelWidth / 2, barLabelY, barLabelWidth, BAR_LABEL_HEIGHT, ARC_SIZE, ARC_SIZE); | ||
| graphics2D.setColor(textColor); | ||
| drawStringCentered(graphics2D,totalText,centerX, barLabelY + 29); |
There was a problem hiding this comment.
Maybe this magic number (29) should be moved to a constant?
| assertEquals(actualImage.getRGB(x, y),expectedImage.getRGB(x, y),() -> "Image does not match.\nActual image:"+actualImageBase64); | ||
| } | ||
| } | ||
| return true; |
There was a problem hiding this comment.
I don't think there's a reason to return anything here. Just make it void.
|
|
||
| for (int y = 0; y < actualImage.getHeight(); y++) { | ||
| for (int x = 0; x < actualImage.getWidth(); x++) { | ||
| assertEquals(actualImage.getRGB(x, y),expectedImage.getRGB(x, y),() -> "Image does not match.\nActual image:"+actualImageBase64); |
There was a problem hiding this comment.
I think it would be useful to include the coordinates in the message here.
| for (int i = 0; i < 13; i++) { | ||
| int segments = random.nextInt(3,5); | ||
| List<Pair<Color, Double>> parts = new ArrayList<>(); | ||
| private static List<Pair<String, Plotter.Bar>> testData0() { |
There was a problem hiding this comment.
I think having descriptive names for the test data methods would be useful. I guess you can just call this testData (or createTestData) and then use names like testDataSmall and createEmptyTestData or similar.
| for (int i = 0; i < 13; i++) { | ||
| int segments = random.nextInt(3,5); | ||
| List<Pair<Color, Double>> parts = new ArrayList<>(); | ||
| private static List<Pair<String, Plotter.Bar>> testData0() { |
There was a problem hiding this comment.
I also think it would be good to have a bar with no segments in one of the test data methods.

redesign the help statistics plot.