The purpose of this example is to implement a simple pie chart with the following effect:
Characteristics:
1. Easy to use, put in an XML layout file, and then set the content in your code, namely:
Piechartview Piechartview = (piechartview) Findviewbyid (R.id.pie_chart); piechartview.pieitembean[] items = new piechartview.pieitembean[]{ new Piechartview.pieitembean ("entertainment", +), New Piechartview.pieitembean ("Travel", New Piechartview.pieitembean ("Learning"), new Piechartview.pieitembean ("Interpersonal", "Piechartview.pieitembean"), New ("Traffic"), New Piechartview.pieitembean ("Dining", 480) }; Piechartview.setpieitems (items);
2. Number of items, size and line position, the length is adaptive. The left entry is underlined on the left, the right entry is underlined on the right, the text description is aligned with the percent center, and the text "underline" is adaptive to the text length. For very small entries, the polyline is automatically extended to avoid text masking as much as possible
Core code: Piechartview.java:
public class Piechartview extends View {private int screenw, screenh; /** * The paint to draw text, pie and line. */Private Paint Textpaint, Piepaint, Linepaint; /** * The center and the radius of the pie. */private int Piecenterx, piecentery, Pieradius; /** * The Oval to draw the oval in. */Private RECTF pieoval; private float Smallmargin; Private int[] Mpiecolors = new int[]{color.red, Color.green, Color.Blue, Color.yellow, Color.magenta, Color.CYAN}; Private pieitembean[] Mpieitems; private float Totalvalue; Public Piechartview (Context context) {super (context); Init (context); } public Piechartview (context context, AttributeSet Attrs) {Super (context, attrs); Init (context); } public Piechartview (context context, AttributeSet attrs, int defstyleattr) {Super (context, Attrs, Defstyleatt R); Init (context); } private void Init (context context) {//init screen Screenw = SCREENUTILS.GETSCREENW (context); Screenh = screenutils.getscreenh (context); Piecenterx = SCREENW/2; Piecentery = SCREENH/3; Pieradius = SCREENW/4; Smallmargin = screenutils.dp2px (context, 5); Pieoval = new RECTF (); Pieoval.left = Piecenterx-pieradius; Pieoval.top = Piecentery-pieradius; Pieoval.right = Piecenterx + Pieradius; Pieoval.bottom = Piecentery + Pieradius; The paint to draw text. Textpaint = new Paint (); Textpaint.setantialias (TRUE); Textpaint.settextsize (screenutils.dp2px (context, 16)); The paint to draw circle. Piepaint = new Paint (); Piepaint.setantialias (TRUE); Piepaint.setstyle (Paint.Style.FILL); The paint to draw line to show the concrete text linepaint = new paint (); Linepaint.setantialias (TRUE); Linepaint.setstrokewidth (screenutils.dp2px (context, 1)); }//the degree position of The last item Arc ' s center. private float lastdegree = 0; The count of the continues ' small ' item. private int addtimes = 0; @Override protected void OnDraw (canvas canvas) {super.ondraw (canvas); if (mpieitems! = null && mpieitems.length > 0) {float start = 0.0f; for (int i = 0; i < mpieitems.length; i++) {//draw pie piepaint.setcolor (mpiecolors[i% Mpiecolors.length]); Float sweep = Mpieitems[i].getitemvalue ()/totalvalue * ; Canvas.drawarc (Pieoval, start, Sweep, true, Piepaint); Draw line away from the pie float radians = (float) ((start + SWEEP/2)/Math.PI); Float Linestartx = Piecenterx + Pieradius * 0.7f * (float) (Math.Cos (radians)); Float Linestarty = piecentery + Pieradius * 0.7f * (float) (Math.sin (radians)); float linestopx, linestopy; Float RatE if (GetOffset (start + SWEEP/2) >) {rate = 1.3f; } else if (GetOffset (start + SWEEP/2) >) {rate = 1.2f; } else {rate = 1.1f; //if the item is very small and make the text further away from the pie to avoid being hided by other text. if (start + SWEEP/2-Lastdegree <) {addtimes++; Rate + = 0.2f * addtimes; } else {addtimes = 0; } linestopx = Piecenterx + Pieradius * rate * (float) (Math.Cos (radians)); Linestopy = piecentery + Pieradius * rate * (float) (Math.sin (radians)); Canvas.drawline (Linestartx, Linestarty, Linestopx, Linestopy, Linepaint); Write text String itemtypetext = Mpieitems[i].getitemtype (); String Itempercenttext = Utility. Formatfloat (Mpieitems[i].getitemvalue ()/totalvalue * 100) + "%"; float Itemtypetextlen = Textpaint.measuretext (Itemtypetext); float Itempercenttextlen = Textpaint.measuretext (Itempercenttext); float linetextwidth = Math.max (Itemtypetextlen, Itempercenttextlen); float textstartx = linestopx; float textstarty = Linestopy-smallmargin; float percentstartx = linestopx; Float Percentstarty = linestopy + textpaint.gettextsize (); if (Linestartx > Piecenterx) {textstartx + = (Smallmargin + math.abs (itemtypetextlen-linetextwidth )/2); Percentstartx + = (Smallmargin + math.abs (itempercenttextlen-linetextwidth)/2); } else {textstartx-= (Smallmargin + linetextwidth-math.abs (itemtypetextlen-linetextwidth)/2); Percentstartx-= (Smallmargin + linetextwidth-math.abs (ItemPErcenttextlen-linetextwidth)/2); } canvas.drawtext (Itemtypetext, Textstartx, Textstarty, Textpaint); Draw percent Text Canvas.drawtext (Itempercenttext, Percentstartx, Percentstarty, Textpaint); Draw text underline float textlinestopx = linestopx; if (Linestartx > Piecenterx) {textlinestopx + = (linetextwidth + smallmargin * 2); } else {textlinestopx-= (linetextwidth + smallmargin * 2); } canvas.drawline (Linestopx, Linestopy, Textlinestopx, Linestopy, Linepaint); Lastdegree = start + SWEEP/2; Start + = sweep; }}} public pieitembean[] Getpieitems () {return mpieitems; } public void Setpieitems (pieitembean[] pieitems) {this.mpieitems = Pieitems; Totalvalue = 0; for (Pieitembean Item:mpieitems) { Totalvalue + = Item.getitemvalue (); } invalidate (); } private float GetOffset (float radius) {int a = (int) (radius% /90); Switch (a) {case 0:return radius; Case 1:return 180-radius; Case 2:return radius-180; Case 3:return -radius; } return radius; } static class Pieitembean {private String itemType; private float Itemvalue; Pieitembean (String itemType, float itemvalue) {this.itemtype = ItemType; This.itemvalue = Itemvalue; } public String Getitemtype () {return itemType; } public void Setitemtype (String itemType) {this.itemtype = ItemType; } public float GetItemValue () {return itemvalue; } public void Setitemvalue (float itemvalue) {this.itemvalue = Itemvalue; } }}
Android: Use canvas to draw a pie chart (automatically adapts to the number/size of items)