From 1404f1773c4c3615ed65cef573b7df458b910108 Mon Sep 17 00:00:00 2001 From: Bane Stojkovic Date: Tue, 6 Oct 2026 22:23:13 +0200 Subject: [PATCH] color selection for bar graph --- .../components/displays/LEDBarGraph.java | 119 +++++++++++++++--- .../components/displays/LEDBarGraphTest.java | 67 ++++++++++ 2 files changed, 170 insertions(+), 16 deletions(-) diff --git a/diylc/diylc-library/src/main/java/org/diylc/components/displays/LEDBarGraph.java b/diylc/diylc-library/src/main/java/org/diylc/components/displays/LEDBarGraph.java index 8a04626e..6a4fc947 100644 --- a/diylc/diylc-library/src/main/java/org/diylc/components/displays/LEDBarGraph.java +++ b/diylc/diylc-library/src/main/java/org/diylc/components/displays/LEDBarGraph.java @@ -87,6 +87,9 @@ public class LEDBarGraph extends AbstractLabeledComponent { public static Color SEGMENT_GREEN = Color.decode("#43A047"); public static Color SEGMENT_YELLOW = Color.decode("#FDD835"); public static Color SEGMENT_RED = Color.decode("#E53935"); + public static Color SEGMENT_BLUE = Color.decode("#1E88E5"); + public static Color SEGMENT_ORANGE = Color.decode("#FB8C00"); + public static Color SEGMENT_WHITE = Color.decode("#EEEEEE"); public static int EDGE_RADIUS = 4; public static Size PIN_SIZE = new Size(0.04d, SizeUnit.in); @@ -106,6 +109,7 @@ public class LEDBarGraph extends AbstractLabeledComponent { private String value = ""; private Orientation orientation = Orientation.DEFAULT; private Segments segments = Segments._10; + private BarColor barColor = BarColor.GREEN_YELLOW_RED; private Color bodyColor = BODY_COLOR; private Color borderColor = BORDER_COLOR; private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0)}; @@ -158,23 +162,24 @@ public class LEDBarGraph extends AbstractLabeledComponent { body = null; } + @EditableProperty(name = "Color") + public BarColor getBarColor() { + if (barColor == null) { + barColor = BarColor.GREEN_YELLOW_RED; + } + return barColor; + } + + public void setBarColor(BarColor barColor) { + this.barColor = barColor; + } + /** - * The colour of one segment, counted from the top of the scale. Red marks the top of the range, - * the two below it are yellow and everything under that is green, so the proportions shift with - * the segment count rather than the bands being fixed fractions: nine green on a twelve segment - * part, five on an eight. - * - *

This is a rule rather than a property. The trade is that a single-colour bar -- all red or - * all green, both of which are sold -- can no longer be drawn. + * The colour of one segment, counted from the top of the scale. Delegates to the selected + * {@link BarColor}. */ private Color getSegmentColor(int index) { - if (index == 0) { - return SEGMENT_RED; - } - if (index <= 2) { - return SEGMENT_YELLOW; - } - return SEGMENT_GREEN; + return getBarColor().getSegmentColor(index, getSegments().getCount()); } @EditableProperty(name = "Body") @@ -202,8 +207,8 @@ public class LEDBarGraph extends AbstractLabeledComponent { } /** - * Puts the segment count in the BOM's value column, so an eight, a ten and a twelve segment part - * are three rows rather than one. Without this they would collapse: the inherited implementation + * Puts the segment count and color in the BOM's value column, so different variants are + * separate rows rather than one. Without this they would collapse: the inherited implementation * returns {@link #getValue()}, which is the part number and is usually blank, and {@code * BomMaker} groups on the type name and the value together. * @@ -215,6 +220,9 @@ public class LEDBarGraph extends AbstractLabeledComponent { @Override public String getValueForDisplay() { String variant = getSegments().toString(); + if (getBarColor() != BarColor.GREEN_YELLOW_RED) { + variant += ", " + getBarColor(); + } String partNumber = getValue(); return partNumber == null || partNumber.trim().isEmpty() ? variant : variant + ", " + partNumber.trim(); @@ -524,4 +532,83 @@ public class LEDBarGraph extends AbstractLabeledComponent { /** Anode and cathode per segment, split evenly between the two rows. */ public int getPinCount() { return count * 2; } } + + public enum BarColor { + GREEN_YELLOW_RED("Green-Yellow-Red"), + BLUE_GREEN_YELLOW_RED("Blue-Green-Yellow-Red"), + RED("Red"), + GREEN("Green"), + YELLOW("Yellow"), + BLUE("Blue"), + ORANGE("Orange"), + WHITE("White"); + + private final String label; + + BarColor(String label) { + this.label = label; + } + + @Override + public String toString() { + return label; + } + + public Color getSegmentColor(int index, int totalSegments) { + switch (this) { + case RED: + return SEGMENT_RED; + case GREEN: + return SEGMENT_GREEN; + case YELLOW: + return SEGMENT_YELLOW; + case BLUE: + return SEGMENT_BLUE; + case ORANGE: + return SEGMENT_ORANGE; + case WHITE: + return SEGMENT_WHITE; + case BLUE_GREEN_YELLOW_RED: + int redCount; + int yellowCount; + int blueCount; + if (totalSegments >= 12) { + redCount = 2; + yellowCount = 3; + blueCount = 2; + } else if (totalSegments >= 10) { + redCount = 2; + yellowCount = 3; + blueCount = 1; + } else if (totalSegments >= 8) { + redCount = 1; + yellowCount = 2; + blueCount = 1; + } else { + redCount = 1; + yellowCount = 1; + blueCount = 1; + } + if (index < redCount) { + return SEGMENT_RED; + } + if (index < redCount + yellowCount) { + return SEGMENT_YELLOW; + } + if (index >= totalSegments - blueCount) { + return SEGMENT_BLUE; + } + return SEGMENT_GREEN; + case GREEN_YELLOW_RED: + default: + if (index == 0) { + return SEGMENT_RED; + } + if (index <= 2) { + return SEGMENT_YELLOW; + } + return SEGMENT_GREEN; + } + } + } } diff --git a/diylc/diylc-library/src/test/java/org/diylc/components/displays/LEDBarGraphTest.java b/diylc/diylc-library/src/test/java/org/diylc/components/displays/LEDBarGraphTest.java index 08814095..fa276748 100644 --- a/diylc/diylc-library/src/test/java/org/diylc/components/displays/LEDBarGraphTest.java +++ b/diylc/diylc-library/src/test/java/org/diylc/components/displays/LEDBarGraphTest.java @@ -27,6 +27,7 @@ import java.awt.geom.Rectangle2D; import org.diylc.appframework.miscutils.ConfigurationManager; import org.diylc.common.IComponentTransformer; import org.diylc.common.Orientation; +import org.diylc.components.displays.LEDBarGraph.BarColor; import org.diylc.components.displays.LEDBarGraph.Segments; import org.diylc.components.transform.LEDBarGraphTransformer; import org.junit.Assert; @@ -349,6 +350,72 @@ public class LEDBarGraphTest { Assert.assertEquals(Orientation._180, vertical.getOrientation()); } + @Test + public void singleColorsRenderUniformSegments() throws Exception { + java.lang.reflect.Method segmentColor = + LEDBarGraph.class.getDeclaredMethod("getSegmentColor", int.class); + segmentColor.setAccessible(true); + + BarColor[] singleColors = new BarColor[] { + BarColor.RED, BarColor.GREEN, BarColor.YELLOW, BarColor.BLUE, BarColor.ORANGE, + BarColor.WHITE + }; + + for (BarColor color : singleColors) { + LEDBarGraph graph = bar(Segments._10); + graph.setBarColor(color); + for (int i = 0; i < 10; i++) { + Assert.assertEquals("segment " + i + " for " + color, + color.getSegmentColor(i, 10), segmentColor.invoke(graph, i)); + } + } + } + + @Test + public void blueGreenYellowRedDistribution() throws Exception { + java.lang.reflect.Method segmentColor = + LEDBarGraph.class.getDeclaredMethod("getSegmentColor", int.class); + segmentColor.setAccessible(true); + + LEDBarGraph graph10 = bar(Segments._10); + graph10.setBarColor(BarColor.BLUE_GREEN_YELLOW_RED); + Assert.assertEquals(LEDBarGraph.SEGMENT_RED, segmentColor.invoke(graph10, 0)); + Assert.assertEquals(LEDBarGraph.SEGMENT_RED, segmentColor.invoke(graph10, 1)); + Assert.assertEquals(LEDBarGraph.SEGMENT_YELLOW, segmentColor.invoke(graph10, 2)); + Assert.assertEquals(LEDBarGraph.SEGMENT_YELLOW, segmentColor.invoke(graph10, 3)); + Assert.assertEquals(LEDBarGraph.SEGMENT_YELLOW, segmentColor.invoke(graph10, 4)); + Assert.assertEquals(LEDBarGraph.SEGMENT_GREEN, segmentColor.invoke(graph10, 5)); + Assert.assertEquals(LEDBarGraph.SEGMENT_GREEN, segmentColor.invoke(graph10, 8)); + Assert.assertEquals(LEDBarGraph.SEGMENT_BLUE, segmentColor.invoke(graph10, 9)); + + LEDBarGraph graph4 = bar(Segments._4); + graph4.setBarColor(BarColor.BLUE_GREEN_YELLOW_RED); + Assert.assertEquals(LEDBarGraph.SEGMENT_RED, segmentColor.invoke(graph4, 0)); + Assert.assertEquals(LEDBarGraph.SEGMENT_YELLOW, segmentColor.invoke(graph4, 1)); + Assert.assertEquals(LEDBarGraph.SEGMENT_GREEN, segmentColor.invoke(graph4, 2)); + Assert.assertEquals(LEDBarGraph.SEGMENT_BLUE, segmentColor.invoke(graph4, 3)); + } + + @Test + public void colorVariantDistinguishesBomRow() { + LEDBarGraph defaultGraph = bar(Segments._10); + LEDBarGraph redGraph = bar(Segments._10); + redGraph.setBarColor(BarColor.RED); + LEDBarGraph bgyrGraph = bar(Segments._10); + bgyrGraph.setBarColor(BarColor.BLUE_GREEN_YELLOW_RED); + + Assert.assertEquals("10 Segment", defaultGraph.getValueForDisplay()); + Assert.assertEquals("10 Segment, Red", redGraph.getValueForDisplay()); + Assert.assertEquals("10 Segment, Blue-Green-Yellow-Red", bgyrGraph.getValueForDisplay()); + } + + @Test + public void barColorDefaultsWhenNull() { + LEDBarGraph graph = new LEDBarGraph(); + graph.setBarColor(null); + Assert.assertEquals(BarColor.GREEN_YELLOW_RED, graph.getBarColor()); + } + private static LEDBarGraph bar(Segments segments) { LEDBarGraph graph = new LEDBarGraph(); graph.setSegments(segments);