0

i'd like to show some statistic data on a simple line (in Java, Swing). It should look like this:

enter image description here

But after hours of searching, i couldn't find such a diagram... i even don't know a name for it... it looks a little bit like a timeline diagram with milestones on it... a standard lib would be great...

Anybody an idea? Any hints?

user3227576
  • 554
  • 8
  • 22
  • Design your own. It's just a matter of calculating proportions. You choose a length for your line based on the size of the window, and then mark the positions on that line according to their ratios to the real value. – RealSkeptic Feb 11 '18 at 09:25

2 Answers2

0

The closest one I can suggest is Box Chart with JFreeChart:

JFreeChart Box and Whisker Demo

JFreeChart does have a quite steep learning curve you need to decide whether you use its component or implement your own JComponent.

Paul
  • 21
  • 2
  • And I know it is not exactly the same as your diagram (not horizontal, not showing median/average) but it is open source you potentially tweak the source to get the one you want. – Paul Feb 12 '18 at 02:00
  • Thank you... i will give it a try and answer, what i could manage with it. You will read me in the next few days... – user3227576 Feb 12 '18 at 11:48
0

As user RealSceptic suggested, i've designed my own diagram. It's very basic but may be it's helpful for somebody in the future, so i share it:

public class BasicLineChart extends JPanel {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private static final int GRAPH_LINE_TOP_DISTANCE = 50;
    private static final int GRAPH_LINE_LEFT_RIGHT_DISTANCE = 30;

    private static final int VERTICAL_LINE_START_POS = 30;
    private static final int VERTICAL_LINE_END_POS = 70;

    private Map<String, Money> statisticData;


    /**
     * Sets the statistic data which is used to paint the graph
     * 
     * @param statisticData
     */
    public void setStatisticData(Map<String, Money> statisticData) {
        if (statisticData == null || statisticData.values() == null || statisticData.values().size() < 2)
            throw new IllegalArgumentException("There must be at least 2 static values to create this chart!");
        this.statisticData = statisticData;
    }

    private void __paintVerticalLine(Graphics2D g2d, Money currentValue, Money minValue, Money maxValue, String label) {
        int lineWidthPosition = GRAPH_LINE_LEFT_RIGHT_DISTANCE + __calcWidthPositionForVerticalLine(currentValue.getAmount(), minValue.getAmount(), maxValue.getAmount());
        g2d.drawLine(lineWidthPosition, VERTICAL_LINE_START_POS, lineWidthPosition, VERTICAL_LINE_END_POS);

        __drawString(g2d, label, lineWidthPosition, VERTICAL_LINE_START_POS - 5);
        __drawString(g2d, currentValue.toString(), lineWidthPosition, VERTICAL_LINE_END_POS + 20);
    }

    private void __drawString(Graphics2D g2d, String text, int lineWidthPosition, int verticalPosition) {
        int labelStartTextPosition = lineWidthPosition - (text.length()/2*7);
        g2d.drawString(text, labelStartTextPosition, verticalPosition);
    }

    private int __calcWidthPositionForVerticalLine(BigDecimal currentValue, BigDecimal minValue, BigDecimal maxValue) {
        BigDecimal percentage = __calcPositionInPercentage(currentValue, minValue, maxValue);
        int width = this.getWidth();
        width = width - (GRAPH_LINE_LEFT_RIGHT_DISTANCE * 2);
        BigDecimal result = new BigDecimal(width).multiply(percentage);
        return result.intValue();
    }

    private BigDecimal __calcPositionInPercentage(BigDecimal currentValue, BigDecimal minValue, BigDecimal maxValue) {
        if (currentValue.compareTo(maxValue) > 0 || currentValue.compareTo(minValue) < 0)
            throw new IllegalArgumentException("Value must be between min and maxvalue!");
        if (minValue.compareTo(currentValue) == 0)
            return BigDecimal.ZERO;
        if (maxValue.compareTo(currentValue) == 0)
            return BigDecimal.ONE;

        BigDecimal tmp = currentValue.subtract(minValue);
        return tmp.divide(maxValue.subtract(minValue), 5, RoundingMode.HALF_UP);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.BLUE);
        Stroke stroke = new BasicStroke(5f, BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE);
        g2d.setStroke(stroke);

        //paint the horizontal line
        g2d.drawLine(GRAPH_LINE_LEFT_RIGHT_DISTANCE, GRAPH_LINE_TOP_DISTANCE, this.getWidth() - GRAPH_LINE_LEFT_RIGHT_DISTANCE,
                GRAPH_LINE_TOP_DISTANCE);

        //paint the vertical lines including the labels
        if (statisticData != null){
            Money minValue = Collections.min(statisticData.values());
            Money maxValue = Collections.max(statisticData.values());
            for (String label : this.statisticData.keySet()){
                __paintVerticalLine(g2d, this.statisticData.get(label), minValue, maxValue, label);
            }
        }
    }

}
user3227576
  • 554
  • 8
  • 22