【问题标题】:Pie Chart not showing expected output饼图未显示预期输出
【发布时间】:2016-04-12 01:26:03
【问题描述】:

我正在尝试使我的饼图与模拟器运行期间更改的数据保持同步。

我的问题是饼图没有以正确的方式显示数据,我不知道问题出在哪里。

 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);

在这里我计算弧的角度..

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);

这部分应该填充它,在某些情况下,整个字符都填充为橙色,而在其他情况下,它是 99% 的红色和一条蓝色的细线。例如,而不是 30%、40%、30%。

黄图:

红/蓝图:

【问题讨论】:

  • 我们大多数人都很难猜出哪里出了问题,因为我们无法测试小的孤立代码。我们不希望看到一个完整的大型程序,因为这会让我们不知所措,其中大部分与您的问题完全无关,但是当发布者付出一点努力来创建一个小的可编译和可运行演示时,我们非常感谢程序,mcve。请查看链接以了解有关我们要求您发布的内容的更多详细信息。
  • 还有这个:" My issue is that the piechart is not showing the data the correct way..."——告诉我们一点用处。您的程序行为异常究竟有多糟糕?细节很重要。
  • 360/percentageAdHoc*100; 360 看起来很可疑。 Java 三角函数通常以弧度为单位。
  • 建议 1:如果您仍然需要我们的帮助,请再次考虑创建并发布 minimal reproducible example——您是否愿意这样做取决于您,但它会再次帮助您 更容易。建议 2:大部分代码应该在 paintComponent 之外,在单独的 且易于测试 方法中。这可以使您的调试更容易。

标签: java swing pie-chart java-2d angle


【解决方案1】:

也许您想首先确保您的百分比计算是正确的。

adhocCars/totalAmountOfCars * 100;

应该是

100/totalAmountOfCars * adhocCars;

【讨论】:

    【解决方案2】:

    您的问题可能是您如何调用Graphics#fillArc(...)。如果您查看Graphics API,尤其是这种方法,您会看到:

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

    注意最后一个参数 arcAngle 的描述是:

    arcAngle - 弧的角度范围,相对于起始角度。

    您可能会调用该方法,就好像它表示圆弧的最终度数,但这不是应该调用它的方式。同样,它应该以度数表示弧的范围

    例如:

    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();
                }
            });
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-09-19
      • 1970-01-01
      • 1970-01-01
      • 2015-07-28
      • 1970-01-01
      • 2022-11-26
      • 2021-07-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多