lloydd4
lloydd4

Reputation: 57

Pie Chart not showing expected output

I'm trying to keep my piechart up to date to the data that changes during the simulator run.

My issue is that the piechart is not showing the data the correct way and I've no clue what the issue is.

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

        int totalAmountOfCars = this.adhocCars + this.reservationCars + this.parkpassCars;
        float percentageAdHoc = totalAmountOfCars <= 0 || this.adhocCars <= 0 ? 0 : adhocCars/totalAmountOfCars * 100;
        float percentageParkPass = totalAmountOfCars <= 0 || this.parkpassCars <= 0 ? 0 :parkpassCars/totalAmountOfCars * 100;
        float percentageReservation = totalAmountOfCars <= 0 || this.reservationCars <= 0 ? 0 :reservationCars/totalAmountOfCars * 100;


        float adHocAngle = totalAmountOfCars <= 0 || this.adhocCars <= 0 ? 0 : 360/percentageAdHoc*100;
        float parkPassAngle = totalAmountOfCars <= 0 || this.parkpassCars <= 0 ? 0 : 360/percentageParkPass*100;
        float reservationAngle = totalAmountOfCars <= 0 || this.reservationCars <= 0 ? 0 : 360/percentageReservation*100;

        Dimension prefSize = this.getPreferredSize();
        g.setColor(Color.WHITE);
        g.fillRect(prefSize.width/2, prefSize.height/2, 200, 200);

Here I calculate the angles for the arcs..

g.setColor(Color.RED);
g.fillArc(prefSize.width/2 + 10, prefSize.height/2 + 10, 180, 180, 0,(int)adHocAngle);
g.setColor(Color.BLUE);
g.fillArc(prefSize.width/2 + 10, prefSize.height/2 + 10, 180, 180, (int)adHocAngle, (int)adHocAngle+(int)parkPassAngle);
g.setColor(Color.ORANGE);
g.fillArc(prefSize.width/2 + 10, prefSize.height/2 + 10, 180, 180,(int)adHocAngle+(int)parkPassAngle, (int)reservationAngle);

This part should fill it, in some cases the entire chars is filled orange and in other cases its for 99% red with a tiny line of blue. Instead of 30%,40%,30% for example.

Yellow Chart:
enter image description here

Red/Blue Chart:
enter image description here

Upvotes: 1

Views: 344

Answers (2)

Apart
Apart

Reputation: 11

Maybe you want to make sure your calculations for percentages are correct first.

adhocCars/totalAmountOfCars * 100;

Should be

100/totalAmountOfCars * adhocCars;

Upvotes: 1

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

Your problem may be how you're calling Graphics#fillArc(...). If you look at the Graphics API, and in particular at this method, you'll see:

public abstract void fillArc(int x,  
                             int y,
                             int width,
                             int height,
                             int startAngle,
                             int arcAngle)

Note that the description of the last parameter, arcAngle, states:

arcAngle - the angular extent of the arc, relative to the start angle.

You may be calling the method as if it represented the final degree angle of the arc, but that's not how it should be called. Again it should represent the extent of the arc in degrees.

For example:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.*;

@SuppressWarnings("serial")
public class PieDemo extends JPanel {
    private static final int PREF_W = 600;
    private static final int PREF_H = PREF_W;
    private static final Color BG = Color.WHITE;
    private static final int GAP = 40;
    public static final int TIMER_DELAY = 400;
    private int redPercent = 0;
    private int bluePercent = 0;
    // green will be remainder

    public PieDemo() {
        setBackground(BG);
        add(new JButton(new StartDemoAction("Start", KeyEvent.VK_S)));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        int redAngle = (redPercent * 360) / 100;
        int blueAngle = (bluePercent * 360) / 100;
        int greenAngle = 360 - redAngle - blueAngle;
        greenAngle = Math.max(greenAngle, 0);
        int startAngle = 0;
        startAngle = drawPie(g, Color.green, startAngle, greenAngle);
        startAngle = drawPie(g, Color.RED, startAngle, redAngle);
        startAngle = drawPie(g, Color.BLUE, startAngle, blueAngle);
    }

    private int drawPie(Graphics g, Color color, int startAngle, int arcAngle) {
        int x = GAP;
        int y = GAP;
        int w = getWidth() - 2 * GAP;
        int h = getHeight() - 2 * GAP;
        g.setColor(color);
        g.fillArc(x, y, w, h, startAngle, arcAngle);
        return startAngle + arcAngle;
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    private class StartDemoAction extends AbstractAction {
        private Timer timer = null;
        public StartDemoAction(String name, int mnemonic) {
            super(name);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (timer != null && timer.isRunning()) {
                return;
            }
            redPercent = 0;
            bluePercent = 0;
            repaint();
            timer = new Timer(TIMER_DELAY, new TimerListener());
            timer.start();
        }
    }

    private class TimerListener implements ActionListener {
        private static final int BOUND = 10;
        private Random random = new Random();

        @Override
        public void actionPerformed(ActionEvent e) {
            if (redPercent + bluePercent >= 100) {
                ((Timer) e.getSource()).stop();
            } else {
                redPercent += random.nextInt(BOUND);
                bluePercent += random.nextInt(BOUND / 2);

                if (redPercent + bluePercent > 100) {
                    bluePercent = 100 - redPercent;
                }
                repaint();
            }
        }
    }

    private static void createAndShowGui() {
        PieDemo mainPanel = new PieDemo();

        JFrame frame = new JFrame("PieDemo");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

Upvotes: 0

Related Questions