Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 717|回复: 0

Swing画3D饼图 实例

[复制链接]

该用户从未签到

发表于 2011-9-18 12:55:35 | 显示全部楼层 |阅读模式
鼠标点击饼图时,被点击的部分会移动出来。



代码:

package test;   
  
import java.awt.Color;   
import java.awt.FontMetrics;   
import java.awt.Graphics;   
import java.awt.Graphics2D;   
import java.awt.RenderingHints;   
import java.awt.Toolkit;   
import java.awt.event.MouseAdapter;   
import java.awt.event.MouseEvent;   
import java.awt.geom.Arc2D;   
import java.util.ArrayList;   
import java.util.List;   
  
import javax.swing.JFrame;   
import javax.swing.JPanel;   
  
/**  
* 绘制3D效果的饼图  
*   
* @author Biao  
*/  
@SuppressWarnings("serial")   
public class Pies3D extends JPanel {   
    // 在饼图中显示的数据   
    private double[] data = { 10.72, 15.38, 3.74, 10.26, 6.56, 5.69, 10.72, 15.38, 6.15, 18.0 };   
    private Color[] defaultColors; // 预定义饼图的颜色   
    private Pie[] pies;   
  
    private int shadowDepth = 8;   
    int selectedIndex = -1; // 鼠标点击是选中的Arc, -1为没有选中   
  
    public Pies3D() {   
        initColors();   
        initPies(data, defaultColors, shadowDepth);   
  
        // 取得鼠标选中的饼图: arc   
        addMouseListener(new MouseAdapter() {   
            @Override  
            public void mouseClicked(MouseEvent e) {   
                selectedIndex = -1;   
                for (int i = 0; i < pies.length; ++i) {   
                    if (pies.getArc().contains(e.getX(), e.getY())) {   
                        selectedIndex = i;   
                        break;   
                    }   
                }   
                repaint();   
            }   
        });   
    }   
  
    private void initColors() {   
        List colors = new ArrayList();   
        colors.add(getColorFromHex("#FF7321"));   
        colors.add(getColorFromHex("#169800"));   
        colors.add(getColorFromHex("#00E500"));   
        colors.add(getColorFromHex("#D0F15A"));   
        colors.add(getColorFromHex("#AA6A2D"));   
        colors.add(getColorFromHex("#BFDD89"));   
        colors.add(getColorFromHex("#E2FF55"));   
        colors.add(getColorFromHex("#D718A5"));   
        colors.add(getColorFromHex("#00DBFF"));   
        colors.add(getColorFromHex("#00FF00"));   
        defaultColors = colors.toArray(new Color[0]);   
    }   
  
    public void initPies(double[] data, Color[] colors, int shadowDepth) {   
        double sum = 0;   
        for (double d : data) {   
            sum += d;   
        }   
  
        // 初始化Pies   
        List< Arc2D> arcList = new ArrayList< Arc2D>();   
        List< Pie> pieList = new ArrayList< Pie>();   
  
        double arcAngle = 0;   
        int x = 50;   
        int y = 50;   
        int w = 380;   
        int h = (int) (w * 0.618);   
        int startAngle = 30;   
        int sumAngle = 0;   
        for (int i = 0; i < data.length; ++i) {   
            arcAngle = data * 360 / sum;   
            if (i + 1 == data.length && sumAngle < 360) {   
                arcAngle = 360 - sumAngle;   
            }   
  
            Arc2D.Double arc = new Arc2D.Double(x, y, w, h, startAngle, arcAngle, Arc2D.PIE);   
            arcList.add(arc);   
  
            Pie pie = new Pie(arc, colors[i % colors.length], shadowDepth, data);   
            pieList.add(pie);   
  
            sumAngle += arcAngle;   
            startAngle += arcAngle;   
        }   
        pies = pieList.toArray(new Pie[0]);   
    }   
  
    public static Color getColorFromHex(String hex) {   
        try {   
            return new Color(Integer.valueOf(hex.substring(1), 16));   
        } catch (Exception e) {   
            return Color.BLACK;   
        }   
    }   
  
    @Override  
    protected void paintComponent(Graphics g) {   
        super.paintComponent(g);   
        Graphics2D g2d = (Graphics2D) g;   
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);   
  
        showPies(g2d);   
    }   
  
    private void showPies(Graphics2D g2d) {   
        int startIndex = 0; // 从第几个饼图开始绘制   
        int endIndex = pies.length; // 要画的饼图的数量.   
  
        // 一次性绘制完3D效果,然后再绘制饼图的效果比绘制饼图的同时绘制好   
        for (int i = startIndex; i < endIndex; ++i) {   
            if (i != selectedIndex) {   
                g2d.setColor(pies.getColor().darker());   
                g2d.fill(pies.getFrontWall());   
            }   
        }   
  
        // 第一个和最后一个要特殊处理   
        if (selectedIndex != startIndex) {   
            g2d.setColor(pies[startIndex].getColor().darker());   
            g2d.fill(pies[startIndex].getLeftWall());   
        }   
  
        if (selectedIndex != endIndex - 1) {   
            g2d.setColor(pies[endIndex - 1].getColor().darker());   
            g2d.fill(pies[endIndex - 1].getRightWall());   
        }   
  
        // 绘制选中的Arc前一个与后一个的墙   
        if (selectedIndex != -1) {   
            int previousIndex = selectedIndex > startIndex ? (selectedIndex - 1) : endIndex - 1;   
            int nextIndex = (selectedIndex + 1) >= endIndex ? startIndex : (selectedIndex + 1);   
  
            // 前一个画右墙   
            g2d.setColor(pies[previousIndex].getColor().darker());   
            g2d.fill(pies[previousIndex].getRightWall());   
  
            // 后一个画左墙   
            g2d.setColor(pies[nextIndex].getColor().darker());   
            g2d.fill(pies[nextIndex].getLeftWall());   
        }   
  
        FontMetrics metrics = g2d.getFontMetrics();   
        // 绘制饼图,把不需要的部分隐藏掉   
        for (int i = startIndex; i < endIndex; ++i) {   
            if (i != selectedIndex) {   
                Pie p = pies;   
                g2d.setColor(p.getColor());   
                g2d.fill(p.getArc());   
  
                String value = p.getValue() + "%";   
                int w = metrics.stringWidth(value) / 2;   
                g2d.setColor(Color.BLACK);   
                g2d.drawString(value, (int) (p.getLabelPosition().getX() - w),   
                    (int) (p.getLabelPosition().getY()));   
            }   
        }   
  
        // 绘制被选中的饼图   
        if (selectedIndex != -1) {   
            Pie p = pies[selectedIndex].getSelectedPie();   
            g2d.setColor(p.getColor().darker());   
            g2d.fill(p.getFrontWall());   
            g2d.fill(p.getLeftWall());   
            g2d.fill(p.getRightWall());   
  
            g2d.setColor(p.getColor());   
            g2d.fill(p.getArc());   
  
            String value = p.getValue() + "%";   
            int w = metrics.stringWidth(value) / 2;   
            g2d.setColor(Color.BLACK);   
            g2d.drawString(value, (int) (p.getLabelPosition().getX() - w),   
                (int) (p.getLabelPosition().getY()));   
        }   
    }   
  
    private static void createGuiAndShow() {   
        JFrame frame = new JFrame(&quotie with 3D Effect");   
        frame.getContentPane().add(new Pies3D());   
  
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
        int sw = Toolkit.getDefaultToolkit().getScreenSize().width;   
        int sh = Toolkit.getDefaultToolkit().getScreenSize().height;   
        int w = 500;   
        int h = 400;   
        int x = (sw - w) / 2;   
        int y = (sh - h) / 2 - 40;   
        x = x > 0 ? x : 0;   
        y = y > 0 ? y : 0;   
        frame.setBounds(x, y, w, h);   
        frame.setVisible(true);   
    }   
  
    public static void main(String[] args) {   
        createGuiAndShow();   
    }   
}  
package test;   
  
import java.awt.Color;   
import java.awt.geom.Arc2D;   
import java.awt.geom.Area;   
import java.awt.geom.GeneralPath;   
import java.awt.geom.Point2D;   
  
class Pie {   
    private Arc2D arc;   
    private Area frontWall;   
    private Area leftWall;   
    private Area rightWall;   
    private Color color;   
    private int shadowDepth;   
    private Pie selectedPie;   
    private Point2D labelPosition;   
    private double shiftDis = 8; // 被选中的饼图在他的中线上移动的距离   
    private double value;   
  
    public Pie(Arc2D arc, Color color, int shadowDepth, double value) {   
        this.arc = arc;   
        this.color = color;   
        this.value = value;   
        this.shadowDepth = shadowDepth;   
  
        Arc2D arcBottom = new Arc2D.Double(arc.getX(), arc.getY() + shadowDepth, arc.getWidth(),   
            arc.getHeight() + 0, arc.getAngleStart(), arc.getAngleExtent(), Arc2D.CHORD);   
        Point2D[] topPs = getPointsOfArc(arc);   
        Point2D[] bottomPs = getPointsOfArc(arcBottom);   
  
        // Front wall   
        GeneralPath font = new GeneralPath();   
        font.moveTo(topPs[1].getX(), topPs[1].getY());   
        font.lineTo(topPs[2].getX(), topPs[2].getY());   
        font.lineTo(bottomPs[2].getX(), bottomPs[2].getY());   
        font.lineTo(bottomPs[1].getX(), bottomPs[1].getY());   
        font.closePath();   
        this.frontWall = new Area(arcBottom);   
        this.frontWall.add(new Area(font));   
  
        // Left wall   
        GeneralPath left = new GeneralPath();   
        left.moveTo(topPs[0].getX(), topPs[0].getY());   
        left.lineTo(topPs[1].getX(), topPs[1].getY());   
        left.lineTo(bottomPs[1].getX(), bottomPs[1].getY());   
        left.lineTo(topPs[0].getX(), topPs[0].getY());   
        left.closePath();   
        this.leftWall = new Area(left);   
  
        // Right wall   
        GeneralPath right = new GeneralPath();   
        right.moveTo(topPs[0].getX(), topPs[0].getY());   
        right.lineTo(topPs[2].getX(), topPs[2].getY());   
        right.lineTo(bottomPs[2].getX(), bottomPs[2].getY());   
        right.lineTo(topPs[0].getX(), topPs[0].getY());   
        right.closePath();   
        this.rightWall = new Area(right);   
  
        // Label position: 四分之三处   
        Point2D c = getArcCenter();   
        Point2D m = getChordCenter();   
  
        double x = ((m.getX() + c.getX()) / 2 + m.getX()) / 2;   
        double y = ((m.getY() + c.getY()) / 2 + m.getY()) / 2;   
        labelPosition = new Point2D.Double(x, y);   
    }   
  
    // 取得Arc上的三个点,在对Arc: center, left, right.   
    public static Point2D[] getPointsOfArc(Arc2D arc) {   
        Point2D[] points = new Point2D[3];   
        Point2D center = new Point2D.Double(arc.getCenterX(), arc.getCenterY());   
        Point2D left = new Point2D.Double(arc.getStartPoint().getX(), arc.getStartPoint().getY());   
        Point2D right = new Point2D.Double(arc.getEndPoint().getX(), arc.getEndPoint().getY());   
        points[0] = center;   
        points[1] = left;   
        points[2] = right;   
  
        return points;   
    }   
  
    public Pie getSelectedPie() {   
        if (selectedPie == null) {   
            selectedPie = createSeletecdPie();   
        }   
  
        return selectedPie;   
    }   
  
    private Pie createSeletecdPie() {   
        // 沿中线方向移动5个单位   
        Point2D[] ps = getPointsOfArc(arc);   
        Point2D c = ps[0];   
        Point2D m = new Point2D.Double((ps[1].getX() + ps[2].getX()) / 2,   
            (ps[1].getY() + ps[2].getY()) / 2);   
        double dis = Math.sqrt((m.getX() - c.getX()) * (m.getX() - c.getX())   
                + (m.getY() - c.getY()) * (m.getY() - c.getY()));   
  
        double deltaX = shiftDis * (m.getX() - c.getX()) / dis;   
        double deltaY = shiftDis * (m.getY() - c.getY()) / dis;   
  
        Arc2D shiftArc = (Arc2D) arc.clone();   
        shiftArc   
            .setFrame(arc.getX() + deltaX, arc.getY() + deltaY, arc.getWidth(), arc.getHeight());   
  
        return new Pie(shiftArc, color, shadowDepth, value);   
    }   
  
    public Arc2D getArc() {   
        return arc;   
    }   
  
    public void setArc(Arc2D arc) {   
        this.arc = arc;   
    }   
  
    public Area getFrontWall() {   
        return frontWall;   
    }   
  
    public void setFrontWall(Area frontWall) {   
        this.frontWall = frontWall;   
    }   
  
    public Area getLeftWall() {   
        return leftWall;   
    }   
  
    public void setLeftWall(Area leftWall) {   
        this.leftWall = leftWall;   
    }   
  
    public Area getRightWall() {   
        return rightWall;   
    }   
  
    public void setRightWall(Area rightWall) {   
        this.rightWall = rightWall;   
    }   
  
    public Color getColor() {   
        return color;   
    }   
  
    public void setColor(Color color) {   
        this.color = color;   
    }   
  
    public Point2D getLabelPosition() {   
        return labelPosition;   
    }   
  
    public void setLabelPosition(Point2D labelPosition) {   
        this.labelPosition = labelPosition;   
    }   
  
    public double getValue() {   
        return value;   
    }   
  
    public void setValue(double value) {   
        this.value = value;   
    }   
  
    public Point2D getChordCenter() {   
        Point2D[] ps = getPointsOfArc(arc);   
        Point2D m = new Point2D.Double((ps[1].getX() + ps[2].getX()) / 2,   
            (ps[1].getY() + ps[2].getY()) / 2);   
  
        return m;   
    }   
  
    public Point2D getArcCenter() {   
        Point2D[] ps = getPointsOfArc(arc);   
        return ps[0];   
    }   
}  
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2024-6-7 14:03 , Processed in 0.370186 second(s), 46 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表