有没有办法在 Swing 中自定义绘制的图表中间显示项目?

问题描述

有没有办法在图表中间显示一个项目?

使用图表从数据库输出值。

我想将下一个项目放在每个馅饼的中心。

有办法吗?下面是代码

This is Chart Image

public class DrawingPiePanel extends JPanel {
    public DrawingPiePanel() {
    }

    private static final long serialVersionUID = 1L;

    Admin ad = Login.ad;

    String month = ad.year1 + "-01";

    kiosk_dao dao = new kiosk_dao();
    int Kor = dao.SelectSaleMonthRestaurant(month,"한식");
    int Ch = dao.SelectSaleMonthRestaurant(month,"중식");
    int Jp = dao.SelectSaleMonthRestaurant(month,"일식");
    int We = dao.SelectSaleMonthRestaurant(month,"양식");

    public void paint(Graphics g) {
        g.clearRect(0,getWidth(),getHeight());

        int Total = Kor + Ch + Jp + We;
        if (Total != 0) {
            int arc1 = (int) 360.0 * Kor / Total;
            int arc2 = (int) 360.0 * Ch / Total;
            int arc3 = (int) 360.0 * Jp / Total;
            int arc4 = 360 - (arc1 + arc2 + arc3);

            double KorPer = (double) Kor / (double) Total * 100;
            double ChPer = (double) Ch / (double) Total * 100;
            double JpPer = (double) Jp / (double) Total * 100;
            double WePer = (double) We / (double) Total * 100;

            g.setColor(Color.YELLOW);
            g.fillArc(50,20,200,arc1);
            g.setColor(Color.RED);
            g.fillArc(50,arc1,arc2);
            g.setColor(Color.BLUE);
            g.fillArc(50,arc1 + arc2,arc3);
            g.setColor(Color.GREEN);
            g.fillArc(50,arc1 + arc2 + arc3,arc4);
            g.setColor(Color.BLACK);
            g.setFont(new Font("굴림체",Font.PLAIN,12));
            g.drawString(" 한식: 노랑" + String.format("%.2f",KorPer) + "%",300,150);
            g.drawString(" 중식: 빨강" + String.format("%.2f",ChPer) + "%",170);
            g.drawString(" 일식: 파랑" + String.format("%.2f",JpPer) + "%",190);
            g.drawString(" 양식: 초록" + String.format("%.2f",WePer) + "%",210);
            g.drawString(" 총매출액: " + Total + " 원",230);
        }

    }

}

解决方法

我尝试使用 Shape 来绘制弧线,并使用 Area 来计算填充弧线的中心。

它做了一个合理的工作,但并不完美:

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.geom.*;

public class DrawPie extends JPanel
{
    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D)g.create();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        drawArc(g2d,Color.YELLOW,70,"Y");
        drawArc(g2d,Color.RED,80,"R");
        drawArc(g2d,Color.BLUE,150,90,"B");
        drawArc(g2d,Color.GREEN,240,120,"G");

        g2d.dispose();
    }

    private void drawArc(Graphics2D g2d,Color color,int start,int extent,String text)
    {
        g2d.setColor( color );
        Shape shape = new Arc2D.Double(50,50,200,start,extent,Arc2D.PIE);
        g2d.fill( shape );

        Rectangle bounds = new Area(shape).getBounds();
        System.out.println(bounds);
        int centerX = bounds.x + (bounds.width / 2) - 5;
        int centerY = bounds.y + (bounds.height / 2) + 7;
        g2d.setColor( Color.BLACK );
        g2d.drawString(text,centerX,centerY);
    }

    @Override
    public Dimension getPreferredSize()
    {
        return new Dimension(300,300);
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(() ->
        {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(new JScrollPane(new DrawPie()));
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        });
    }
}

对 centerX/Y 值的调整是使用 Graphics 类的真正 FontMetrics 的捷径。 X 值应该是您绘制的文本宽度的一半,Y 值应该是您绘制的高度测试。您可以尝试使用真正的 FontMetrics,看看它是否有所作为。

请注意,这是“最小的、可重现的示例”的示例。示例中仅包含与问题直接相关的代码。任何人都可以复制/粘贴/编译和文本。将来所有的问题都应该包含一个 MRE 来证明问题。

编辑:

我的第二次尝试尝试使用 Andrew 的建议来确定一条直线上的一个点,该点是弧角的一半和半径的一半。

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.geom.*;

public class DrawPie extends JPanel
{
    private int inset = 25;
    private int radius = 100;
    private int diameter = radius * 2;
    private int translation = inset + radius;

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D)g.create();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,Color.CYAN,160,String text)
    {
        g2d.setColor( color );
        Shape shape = new Arc2D.Double(inset,inset,diameter,Arc2D.PIE);
        g2d.fill( shape );

        double radians = Math.toRadians(90 + start + (extent / 2));
        int centerX = (int)(Math.sin(radians) * radius / 2);
        int centerY = (int)(Math.cos(radians) * radius / 2);
        g2d.setColor( Color.BLACK );
        g2d.drawString(text,centerX + translation,centerY + translation);
    }


    @Override
    public Dimension getPreferredSize()
    {
        int size = (inset * 2) + diameter;
        return new Dimension(300,300);
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(() ->
        {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(new JScrollPane(new DrawPie()));
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        });
    }
}

不知道为什么在将角度转换为弧度时需要添加“90”?

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...