在PIECTA切片中间绘制三角形的PyCAR图 我想在皮埃切尔片中间画一个三角形的印版。 此刻,我在切片中间画了一个切片和三角形的PiCHAT,但是三角形不是直角。我需要知道如何以正确的方式定位三角形。我的代码和结果: import java.awt.*; import java.awt.geom.Ellipse2D; import javax.swing.*; class Slice { double value; Color color; public Slice(double value, Color color) { this.value = value; this.color = color; } } class PieChart extends JPanel { private Color a = Color.RED; private Color b = Color.BLUE; private Color c = Color.YELLOW; Slice[] slices = { new Slice(60, a), new Slice(100, b), new Slice(200, c) }; public PieChart(){ } @Override protected void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D)g; super.paintComponent(g2d); this.setBackground(new Color(255,255,255)); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); double total = 0.0D; for (int i = 0; i < slices.length; i++) { total += slices[i].value; } double curValue = 90.0D; int startAngle = 0; for (int i = 0; i < slices.length; i++) { startAngle = (int) (curValue * 360 / total); int arcAngle = (int) (slices[i].value * 360 / total); g2d.setColor(slices[i].color); g2d.fillArc(20, 20, 200, 200, startAngle, arcAngle); g2d.setPaint(Color.BLACK); int x = (int)(110+100*Math.cos(((-(startAngle+(arcAngle/2)))*Math.PI)/180)); int y = (int)(110+100*Math.sin(((-(startAngle+(arcAngle/2)))*Math.PI)/180)); Polygon p = new Polygon(new int[] {x, x+14, x+7}, new int[] {y, y, y-14}, 3); // this values seems to be important g2d.draw(p); g2d.fill(p); curValue += slices[i].value; } } } import java.awt.*; 导入java.awt.geom.Ellipse2D; 导入javax.swing.*; 类切片{ 双重价值; 颜色; 公共切片(双值,彩色){ 这个值=值; 这个颜色=颜色; } } 类PieChart扩展了JPanel{ 专用颜色a=颜色。红色; 专用颜色b=颜色。蓝色; 专用颜色c=颜色。黄色; 切片[]切片={ 新切片(60,a), 新切片(100,b), 新切片(200,c) }; 公共图表(){ } @凌驾 受保护组件(图形g){ Graphics2D g2d=(Graphics2D)g; 超级油漆组件(g2d); 这个.挫折背景(新颜色(255255));; g2d.setRenderingHint(renderingHits.KEY\u抗锯齿,renderingHits.VALUE\u抗锯齿\u开启); 双总=0.0D; 对于(int i=0;i
编辑:应如下所示: 这里我提出了一个解决方案(稍微更改一下算法):在PIECTA切片中间绘制三角形的PyCAR图 我想在皮埃切尔片中间画一个三角形的印版。 此刻,我在切片中间画了一个切片和三角形的PiCHAT,但是三角形不是直角。我需要知道如何以正确的方式定位三角形。我的代码和结果: import java.awt.*; import java.awt.geom.Ellipse2D; import javax.swing.*; class Slice { double value; Color color; public Slice(double value, Color color) { this.value = value; this.color = color; } } class PieChart extends JPanel { private Color a = Color.RED; private Color b = Color.BLUE; private Color c = Color.YELLOW; Slice[] slices = { new Slice(60, a), new Slice(100, b), new Slice(200, c) }; public PieChart(){ } @Override protected void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D)g; super.paintComponent(g2d); this.setBackground(new Color(255,255,255)); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); double total = 0.0D; for (int i = 0; i < slices.length; i++) { total += slices[i].value; } double curValue = 90.0D; int startAngle = 0; for (int i = 0; i < slices.length; i++) { startAngle = (int) (curValue * 360 / total); int arcAngle = (int) (slices[i].value * 360 / total); g2d.setColor(slices[i].color); g2d.fillArc(20, 20, 200, 200, startAngle, arcAngle); g2d.setPaint(Color.BLACK); int x = (int)(110+100*Math.cos(((-(startAngle+(arcAngle/2)))*Math.PI)/180)); int y = (int)(110+100*Math.sin(((-(startAngle+(arcAngle/2)))*Math.PI)/180)); Polygon p = new Polygon(new int[] {x, x+14, x+7}, new int[] {y, y, y-14}, 3); // this values seems to be important g2d.draw(p); g2d.fill(p); curValue += slices[i].value; } } } import java.awt.*; 导入java.awt.geom.Ellipse2D; 导入javax.swing.*; 类切片{ 双重价值; 颜色; 公共切片(双值,彩色){ 这个值=值; 这个颜色=颜色; } } 类PieChart扩展了JPanel{ 专用颜色a=颜色。红色; 专用颜色b=颜色。蓝色; 专用颜色c=颜色。黄色; 切片[]切片={ 新切片(60,a), 新切片(100,b), 新切片(200,c) }; 公共图表(){ } @凌驾 受保护组件(图形g){ Graphics2D g2d=(Graphics2D)g; 超级油漆组件(g2d); 这个.挫折背景(新颜色(255255));; g2d.setRenderingHint(renderingHits.KEY\u抗锯齿,renderingHits.VALUE\u抗锯齿\u开启); 双总=0.0D; 对于(int i=0;i,java,swing,draw,pie-chart,paintcomponent,Java,Swing,Draw,Pie Chart,Paintcomponent,编辑:应如下所示: 这里我提出了一个解决方案(稍微更改一下算法): 公共类图表{ 公共静态void main(字符串[]args){ JFrame=新JFrame(); frame.add(新的PieChart()); 框架设置尺寸(新尺寸(400400)); frame.setDefaultCloseOperation(WindowConstants.DISPOSE\u ON\u CLOSE); EventQueue.invokeLater(()->{ frame.setVisible(tru
公共类图表{
公共静态void main(字符串[]args){
JFrame=新JFrame();
frame.add(新的PieChart());
框架设置尺寸(新尺寸(400400));
frame.setDefaultCloseOperation(WindowConstants.DISPOSE\u ON\u CLOSE);
EventQueue.invokeLater(()->{
frame.setVisible(true);
});
}
公共静态类切片{
双重价值;
颜色;
公共切片(双值、彩色){
这个值=值;
这个颜色=颜色;
}
}
公共静态类PieChart扩展了JPanel{
私有静态最终长serialVersionUID=1L;
专用颜色a=颜色。红色;
专用颜色b=颜色。蓝色;
专用颜色c=颜色。黄色;
切片[]切片={新切片(60,a),新切片(100,b),
新切片(200,c)};
公共图表(){
}
@凌驾
受保护组件(图形g){
Graphics2D g2d=(Graphics2D)g;
超级油漆组件(g2d);
这个.背景(颜色.白色);
g2d.setRenderingHint(RenderingHits.KEY\u ANTIALIASING,RenderingHits.VALUE\u ANTIALIAS\u ON);
int upperLeftX=20;
int upperLeftY=20;
int r=100;
int startAngle=0;
双曲线值=0.0;
对于(int i=0;i底面的半点
intx1=x-(int)(7*Math.sin(qi*Math.PI/180));
int y1=y-(int)(7*Math.cos(qi*Math.PI/180));
intx2=x+(int)(7*Math.sin(qi*Math.PI/180));
int y2=y+(int)(7*Math.cos(qi*Math.PI/180));
int x3=upperLeftX+r+(int)(Math.cos(qi*Math.PI/180)*(r+12));
int y3=upperLeftY+r-(int)(Math.sin(qi*Math.PI/180)*(r+12));
多边形p=新多边形(新int[]{x1,x2,x3},
new int[]{y1,y2,y3},3);//此值似乎
//重要
g2d.draw(p);
g2d.填充(p);
曲线值+=切片[i]。值;
}
}
}
}
我从0点开始做了第一个弧(我想你是有意这么做的)
由于您使用的是fillArc
,它需要int
s,因此向下取整的double
s加起来可能不等于全部金额,并且片之间会有间隙:
相反,请使用Arc2D.Double
以获得更好的精度:
poly
用作基本三角形,面朝上,其底部以0点钟点为中心。每个圆弧都会平移和变换(该多边形的副本),使其底部位于弧长的中心,并向外指向
注意事项:
- 不要在
内部调用paintComponent
,在外部调用它。它使绘制机制在每次重新绘制时自动绘制背景。如果你把它放在里面,你只是用每一次重新绘制来覆盖指令。或者,您可以使用setBackground
将背景设置为白色(或g.clearRect
设置为其他颜色)fillRect
- 重写面板的
方法以与其内容兼容getPreferredSize
- 使用常量(
)insteafinal
public class Chart { public static void main(String[] args) { JFrame frame= new JFrame(); frame.add(new PieChart()); frame.setSize(new Dimension(400, 400)); frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); EventQueue.invokeLater( () ->{ frame.setVisible(true); }); } public static class Slice { double value; Color color; public Slice(double value, Color color) { this.value = value; this.color = color; } } public static class PieChart extends JPanel { private static final long serialVersionUID = 1L; private Color a = Color.RED; private Color b = Color.BLUE; private Color c = Color.YELLOW; Slice[] slices = { new Slice(60, a), new Slice(100, b), new Slice(200, c) }; public PieChart() { } @Override protected void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g; super.paintComponent(g2d); this.setBackground(Color.WHITE); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); int upperLeftX = 20; int upperLeftY = 20; int r = 100; int startAngle = 0; double curValue = 0.0; for (int i = 0; i < slices.length; i++) { startAngle = (int) curValue ; int arcAngle = (int) slices[i].value ; g2d.setColor(slices[i].color); g2d.fillArc(upperLeftX, upperLeftY, r*2, r*2, startAngle, arcAngle); g2d.setPaint(Color.BLACK); double qi = curValue+slices[i].value/2; int x = upperLeftX + r + (int)(Math.cos(qi*Math.PI/180)*r); int y = upperLeftY + r - (int)(Math.sin(qi*Math.PI/180)*r); //point touching the circle (x,y)->half point of the base int x1 = x - (int)(7*Math.sin(qi*Math.PI/180)); int y1 = y - (int)(7*Math.cos(qi*Math.PI/180)); int x2 = x + (int)(7*Math.sin(qi*Math.PI/180)); int y2 = y + (int)(7*Math.cos(qi*Math.PI/180)); int x3 = upperLeftX + r + (int)(Math.cos(qi*Math.PI/180)*(r+12)); int y3 = upperLeftY + r - (int)(Math.sin(qi*Math.PI/180)*(r+12)); Polygon p = new Polygon(new int[] { x1, x2, x3 }, new int[] { y1, y2, y3 }, 3); // this values seems to // be important g2d.draw(p); g2d.fill(p); curValue += slices[i].value; } } } }
class Slice { double value; Color color; public Slice(double value, Color color) { this.value = value; this.color = color; } public Color getColor() { return color; } public double getValue() { return value; } } class PieChart extends JPanel { private final int SIZE = 500, START = 40, START_DEG = 90; private final int TRIG_HBASE = 66, TRIG_HEIGHT = 36; private final int x0 =(START + SIZE / 2), y0 = START; private final Polygon poly; private Color a = Color.RED; private Color b = Color.BLUE; private Color c = Color.YELLOW; Slice[] slices = {new Slice(65, a), new Slice(123, b), new Slice(212, c)}; PieChart() { setBackground(Color.WHITE); int x1 = x0 + TRIG_HBASE, y1 = y0; int x2 = x0 - TRIG_HBASE, y2 = y0; int x3 = x0, y3 = y0 - TRIG_HEIGHT; poly = new Polygon(new int[] {x1, x2, x3}, new int[] {y1, y2, y3}, 3); } @Override protected void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g; super.paintComponent(g2d); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setColor(Color.LIGHT_GRAY); g2d.fillRect(START, START, SIZE, SIZE); double total = 0d; for (Slice slice : slices) { total += slice.getValue(); } double startAngle = START_DEG; double arcAngle, centerAngle; double x, y; for (Slice slice : slices) { arcAngle = (slice.getValue() * 360 / total); g2d.setColor(slice.getColor()); g2d.fill(new Arc2D.Double(START, START, SIZE, SIZE, startAngle, arcAngle, Arc2D.PIE)); centerAngle = Math.toRadians(((startAngle - START_DEG) + arcAngle / 2)); x = (START + SIZE / 2 * (1 - Math.sin(centerAngle))); y = (START + SIZE / 2 * (1 - Math.cos(centerAngle))); AffineTransform trans = AffineTransform.getTranslateInstance(x - x0, y - y0); AffineTransform rot = AffineTransform.getRotateInstance(-centerAngle, x, y); Shape s = trans.createTransformedShape(poly); s = rot.createTransformedShape(s); g2d.setColor(slice.getColor().darker()); g2d.fill(s); startAngle += arcAngle; } } @Override public Dimension getPreferredSize() { return new Dimension(START * 2 + SIZE, START * 2 + SIZE); } }
private final int SIZE = 200, START = 20, START_DEG = 90; private final int TRIG_HBASE = 7, TRIG_HEIGHT = 14;