Android: Use canvas to draw a pie chart (automatically adapts to the number/size of items)

Source: Internet
Author: User
Tags drawtext



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)


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.