Canvas的饼图百分比标注位置计算技巧

来源:互联网 发布:php 数组最大值 编辑:程序博客网 时间:2024/04/30 05:50

如何在一张饼图(Pie Chart)上每个扇形的中心位置标记出百分比先上张最终效果图:




        代码如下

     public class MyViewOne extends View {


private int ScrWidth, ScrHeight;
private float rx, ry;


public MyViewOne(Context context) {
super(context);
// TODO Auto-generated constructor stub


this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);


// 屏幕信息
DisplayMetrics dm = getResources().getDisplayMetrics();
ScrHeight = dm.heightPixels;
ScrWidth = dm.widthPixels;
}


@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);


canvas.drawColor(Color.WHITE);
         
         //画笔初始化
         Paint PaintArc = new Paint();
         PaintArc.setColor(Color.RED);       
                      
         Paint PaintGree = new Paint();
         PaintGree.setColor(Color.GREEN);
         PaintGree.setStyle(Style.FILL);
          
         Paint PaintBlue = new Paint();
         PaintBlue.setColor(Color.BLUE);
         PaintBlue.setStyle(Style.STROKE);
          
         Paint PaintYellow = new Paint();
         PaintYellow.setColor(Color.YELLOW);
         PaintYellow.setStyle(Style.FILL);
          
         //抗锯齿
         PaintArc.setAntiAlias(true);
         PaintYellow.setAntiAlias(true);
         PaintGree.setAntiAlias(true);
                  
         PaintBlue.setTextSize(12);
                      
         float cirX = ScrWidth / 2;
         float cirY = ScrHeight / 3 ;
         float radius = ScrHeight / 5 ;
         //先画个圆确定下显示位置
         canvas.drawCircle(cirX,cirY,radius,PaintGree);
                                  
         float arcLeft = cirX - radius;
         float arcTop  = cirY - radius ;
         float arcRight = cirX + radius ;
         float arcBottom = cirY + radius ;
         RectF arcRF0 = new RectF(arcLeft ,arcTop,arcRight,arcBottom);   
          
         //饼图标题
     //    canvas.drawText("author:xiongchuanliang",60,ScrHeight - 270, PaintBlue);    
          
         //位置计算类  
         XChartCalc xcalc = new XChartCalc();                    
          
         //实际用于计算的半径
         float calcRadius = radius/2;
         
         //初始角度              
         float pAngle1 = 130f; 
         float pAngle2 = 40f; 
         float pAngle3 = 360f - pAngle1 - pAngle2; 
          
         //填充扇形
         canvas.drawArc(arcRF0, 0,pAngle1, true,PaintArc); 
          
         //计算并在扇形中心标注上百分比    130%
         xcalc.CalcArcEndPointXY(cirX, cirY, calcRadius, pAngle1/2); 
         canvas.drawText(Float.toString(pAngle1)+"%", xcalc.getPosX(),xcalc.getPosY(), PaintBlue);  
          
         
         //填充扇形
         canvas.drawArc(arcRF0, pAngle1,pAngle2, true,PaintYellow);   
         
         //计算并在扇形中心标注上百分比   40%
         xcalc.CalcArcEndPointXY(cirX, cirY, calcRadius, pAngle1 + pAngle2/2);               
         canvas.drawText(Float.toString(pAngle2)+"%", xcalc.getPosX(),xcalc.getPosY(), PaintBlue);  
          
         
         //计算并在扇形中心标注上百分比  190%
         xcalc.CalcArcEndPointXY(cirX, cirY, calcRadius, pAngle1 + pAngle2 + pAngle3/2);             
         canvas.drawText(Float.toString(pAngle3)+"%", xcalc.getPosX(),xcalc.getPosY(), PaintBlue);  


}


}



public class XChartCalc {
// Position位置
private float posX = 0.0f;
private float posY = 0.0f;






// 依圆心坐标,半径,扇形角度,计算出扇形终射线与圆弧交叉点的xy坐标
public void CalcArcEndPointXY(float cirX, float cirY, float radius,
float cirAngle) {


// 将角度转换为弧度
float arcAngle = (float) (Math.PI * cirAngle / 180.0);
if (cirAngle < 90) {
posX = cirX + (float) (Math.cos(arcAngle)) * radius;
posY = cirY + (float) (Math.sin(arcAngle)) * radius;
} else if (cirAngle == 90) {
posX = cirX;
posY = cirY + radius;
} else if (cirAngle > 90 && cirAngle < 180) {
arcAngle = (float) (Math.PI * (180 - cirAngle) / 180.0);
posX = cirX - (float) (Math.cos(arcAngle)) * radius;
posY = cirY + (float) (Math.sin(arcAngle)) * radius;
} else if (cirAngle == 180) {
posX = cirX - radius;
posY = cirY;
} else if (cirAngle > 180 && cirAngle < 270) {
arcAngle = (float) (Math.PI * (cirAngle - 180) / 180.0);
posX = cirX - (float) (Math.cos(arcAngle)) * radius;
posY = cirY - (float) (Math.sin(arcAngle)) * radius;
} else if (cirAngle == 270) {
posX = cirX;
posY = cirY - radius;
} else {
arcAngle = (float) (Math.PI * (360 - cirAngle) / 180.0);
posX = cirX + (float) (Math.cos(arcAngle)) * radius;
posY = cirY - (float) (Math.sin(arcAngle)) * radius;
}


}




public float getPosX() {
return posX;
}


public float getPosY() {
return posY;
}
}


0 0