TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
鼠标点击饼图时,被点击的部分会移动出来。

代码:
- 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[i].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[i] * 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[i]);
- 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[i].getColor().darker());
- g2d.fill(pies[i].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[i];
- 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("Pie 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];
- }
- }
-
-
复制代码
源码下载:http://file.javaxxz.com/2014/11/6/235619468.zip |
|