我正在制作一个包含4种不同元素的饼图。我可以让元素出现在JFrame中,但我无法完成饼图圈。这些是要素:
public static class PieChart extends JComponent {
IAPieChart[] pieValue = {new IAPieChart(5, Color.green),
new IAPieChart(4, Color.orange),
new IAPieChart(3, Color.blue),
new IAPieChart(2, Color.red)
};
现在元素已实例化并加载到数组中,我使用此方法绘制它们:
public void paintComponent(Graphics g) {
drawPie((Graphics2D) g, getBounds(), pieValue);
}
此方法将元素放在JFrame上,但只给出了大约120度的圆。 :
void drawPie(Graphics2D g, Rectangle area, IAPieChart[] pieValue){
double sum = 0.0;
for (int i = 0; i < pieValue.length; i++) {
sum += pieValue[i].arcValue;
}
double endPoint = 0.0D;
int arcStart = 0;
for (int i = 0; i < pieValue.length; i++){
endPoint = (int) (endPoint * 360 / sum);
int radius = (int) (pieValue[i].arcValue * 360/ sum);
g.setColor(pieValue[i].color);
g.fillArc(area.x, area.y, area.width, area.height, arcStart , radius);
radius += pieValue[i].arcValue;
}
}
}
我很茫然。我用Java大约需要10周时间,所以这主要是反复试验。我正在寻找一种方法来完成这个圈子。我将值减少到可以显示所有颜色的最低点。任何更大的东西都会消除一种颜色或另一种颜色。
我希望你能提供帮助。这是完整的程序IAPieChart:
package iapiechart;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JComponent;
import javax.swing.JFrame;
class IAPieChart{
double arcValue; // passes a value for the calculation of the arc.
Color color; // holds value for color (expressed as an integer
public IAPieChart(double value, Color color){
this.arcValue = value;
this.color = color;
}
public static class PieChart extends JComponent {
IAPieChart[] pieValue = {new IAPieChart(5, Color.green),
new IAPieChart(4, Color.orange),
new IAPieChart(3, Color.blue),
new IAPieChart(2, Color.red)
};
public void paintComponent(Graphics g) {
drawPie((Graphics2D) g, getBounds(), pieValue);
}
void drawPie(Graphics2D g, Rectangle area, IAPieChart[] pieValue){
double sum = 0.0;
for (int i = 0; i < pieValue.length; i++) {
sum += pieValue[i].arcValue;
}
double endPoint = 0.0D;
int arcStart = 0;
for (int i = 0; i < pieValue.length; i++){
endPoint = (int) (endPoint * 360 / sum);
int radius = (int) (pieValue[i].arcValue * 360/ sum);
g.setColor(pieValue[i].color);
g.fillArc(area.x, area.y, area.width, area.height, arcStart , radius);
radius += pieValue[i].arcValue;
}
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new PieChart());
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
答案 0 :(得分:4)
如果您只想显示饼图,其中arc value
是细分的权重,请更改您的绘图周期。
int arcStart = 0;
for (int i = 0; i < pieValue.length; i++){
int radius = (int) (pieValue[i].arcValue * 360.0 / sum);
g.setColor(pieValue[i].color);
g.fillArc(area.x, area.y, area.width, area.height, arcStart, radius);
arcStart += radius;
}
结果是这样的:
如你所见,有一个小的空白区域,我想,这是由累积的舍入错误引起的。可以通过使用arcValue绘制最后一个段来解决,该弧度补充所有previos的总和为360.
答案 1 :(得分:2)
原始方法中有arcStart
计算的混合。它应该从上一个弧的结尾开始。考虑这个略微修改的方法。评论描述了更新的行。
void drawPie(Graphics2D g, Rectangle area, IAPieChart[] pieValue){
double sum = 0.0;
for (int i = 0; i < pieValue.length; i++) {
sum += pieValue[i].arcValue;
}
double endPoint = 0.0D;
int arcStart = 0;
for (int i = 0; i < pieValue.length; i++){
arcStart = (int) (endPoint * 360 / sum); //old line was: endPoint = (int) (endPoint * 360 / sum);
int radius = (int) (pieValue[i].arcValue * 360/ sum);
g.setColor(pieValue[i].color);
g.fillArc(area.x, area.y, area.width, area.height, arcStart , radius);
endPoint += pieValue[i].arcValue; //old line was: radius += pieValue[i].arcValue;
}
}
它取代了行:
endPoint = (int) (endPoint * 360 / sum);
with:
arcStart = (int) (endPoint * 360 / sum);
并替换行:
radius += pieValue[i].arcValue;
with:
endPoint += pieValue[i].arcValue;
结果如下:
不要忘记在super.paintComponent(g);
中致电paintComponent()
。此外,您可能希望添加抗锯齿渲染提示以使图像平滑一点,即:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
drawPie((Graphics2D) g, getBounds(), pieValue);
}
答案 2 :(得分:1)
你有
double endPoint = 0.0D;
int arcStart = 0;
for (int i = 0; i < pieValue.length; i++){
endPoint = (int) (endPoint * 360 / sum);
...
然而,每次都会将endPoint = 0作为乘以零。尝试制作
endPoint += (int) (endPoint * 360 / sum);
答案 3 :(得分:1)
我了解到我从phcoding和mishadoff的回复中积累了错误的值。然而,根据phcoding的建议,我想出了pieValue数组的附加实例。这两个回复都是丰富的,我的回答也增加了我的经验。
mishadoff:我可以按照您在回复中提到的“权重”定义吗?当我想到重量时,我想象一个弧开始的锚点,然后给出的值是它沿着圆的半径行进的增加量。那很近吗?phcoding&amp; mishadoff:我打算把它放到Applet中你是否预见到这样做的任何问题,例如将这些代码转移到applet中?我问,因为你给我的任何建议都会花费我几个小时的编程时间,而我将需要它们。
非常感谢你们!
版