Android Piechart Pie Chart control

Source: Internet
Author: User
Tags cos drawtext

Write a pie chart to customize the view article today. Since the company's project needs a pie chart, the UI gives the design and the title of the pie frame you're looking for does not match, so you draw one yourself.


1, using preview
Piechart Mchart Mchart = (piechart) Findviewbyid (R.id.piechar); Mchart = (Piechart) Findviewbyid (R.id.pieChar); String[] titles = new string[] {"Wallet balances", "money bag Assets", "Jinbao box Assets"};mchart.settitles (titles); int[] colors = new int[]{0xfff5a002, 0xfffb5a2f,0xff36bc99};mchart.setcolors (colors); Mchart.setvalues (new double[]{999,999,999}); Mchart.postinvalidate ();
You need to pass in the title and the value, each pie color can also be reset, do not pass the color value is used by default. The difficulty of appeased diagram is in mathematical calculation and logical thinking ability.

2 Code Analysis
/** * Get the angle of each value * @return */private float[] Getangles () {if (mvalues = null | | mvalues.length = 0) return null;double sum = 0;int len = mtitles.length;float[] angles = new Float[len];int Gapcount = 0;//pie gap bar number for (int i=0;i<len;i++) {sum + = MV Alues[i];if (mvalues[i]>0) gapcount++;} float angle = 0;pieangle = 360-gapcount*angle_dis;for (int i=0;i<len-1;i++) {Angles[i] = (float) (pieangle*mvalues[i]/ sum); angle + = Angles[i];} if (mvalues[len-1]>0) angles[len-1] = Pieangle-angle;return angles; }
The angle of each value is calculated according to the value passed in, and the pie chart has a gap between 1°, if (mvalues[i]>0) gapcount++, and only if the value is greater than 0 o'clock, only the appeased is added. Pieangle = 360-gapcount*angle_dis; This calculates the angle at which all the loaves occupy the entire circle. if (mvalues[len-1]>0) angles[len-1] = Pieangle-angle; The angle of the last pie is the sum of the angles of the pie, minus the angle of all the preceding loaves, so that the angle of all the loaves is equal to the angle of pieangle. Reduce the fractional error effect of the division operation.
/** * Write a percentage on each pie in the pie chart and must be placed after calculating the angle of each value angles * @param canvas */private void setpiecontenttext (canvas canvas) {float pre = 0; float[] Centerangle = new float[mangles.length];for (int i=0;i<mangles.length;i++) {if (mangles[i] = = 0) continue; Centerangle[i] = ANGLE_DIS+MANGLES[I]/2 + Pre;pre + + mangles[i];} float Cenr = pier*1.0f/2*3/5;float Lastpir = 1.0f;//in order to make all the% ratios equal to 1mtextpaint.setcolor (0xFFFFFFFF); float Cenx = 0;float ceny = 0;for (int i=0;i<centerangle.length;i++) {if (centerangle[i]==0) continue;float xa = (float) (CENR * Math.cos (CEN Terangle[i] (math.pi/180)); float ya = (float) (CENR * Math.sin (centerangle[i] * (math.pi/180))); Cenx = GetWidth () * * .0f/2+xa;ceny = top_padding + PIER*1.0F/2 + ya;mtextpaint.settextsize (mpietextsize);d ouble curPer = numDecimals (mAngles [I]/pieangle]; String permsg = I==centerangle.length-1?percentformat (lastpir):p Ercentformat (curper); Canvas.drawtext (PERMSG, Cenx-gettextwidth (permsg, mpietextsize) *1.0F/2, Ceny+gettextheight (permsg, mpietextsize) *1.0F/2/2, Mtextpaint); Lastpir-= Curper;}} 
This code calculates the angle of the percent text within the circle, centerangle[i] = ANGLE_DIS+MANGLES[I]/2 + pre; the percent text is in the center of each pie. float Cenr = PIER*1.0F/2*3/5; Calculates the distance of the percentage text center to the centre, which can be adjusted as needed, pieR the diameter of the pie chart. As shown, float xa = (float) (CENR * MATH.COS (centerangle[i] * (math.pi/180))); float ya = (float) (CENR * Math.sin (centerangle [i] * (math.pi/180)); Middle xa and ya are the horizontal vertical distances from the text to the center of the circle. Cenx = GetWidth () *1.0f/2+xa; ceny = top_padding + PIER*1.0F/2 + ya;cenx and ceny are the coordinates of the text above the view.


3, custom pie chart source
Import Java.text.decimalformat;import java.util.list;import Android.content.context;import Android.graphics.Canvas ; Import Android.graphics.paint;import Android.graphics.rect;import Android.graphics.rectf;import Android.util.attributeset;import Android.util.typedvalue;import Android.view.view;import cn.golditfin.component.amount.amountutils;/** * Round pie chart control, title how many bars to display, ignoring value * @author Huangyuguang * Create on December 18, 2015 * File Name Piechart.java */public class Piechart extends view{private final float density = getresources (). GE Tdisplaymetrics (). density;/** the angle of the interval between pie charts */private final float Angle_dis = 1;/** left and right space distance */private final float lr_padding = * density;/** top space distance */private final float top_padding = * density;/** pie and bottom text distance */private final float Pie_text_dis = 2 2 * density;/** the distance between the upper and lower lines of text */private final float Text_text_dis = the distance between the bottom of the density;/** and the text, actually bottom_dis+text_text_dis*/ Private final Float Bottom_dis = ten * density;/** the minimum distance between title and value */private Final float Title_value_dis = * Density;/** the color value of each part, the default is 10 colors */private int[] mcolors = new Int[]{0xfff5a002,0xfffb5a2f,0xff36bc99,0xff43f90c,0xff181a18, 0XFFF802F6,0XFF022DF8,0XFFECF802,0XFF02F8E8,0XFFEA0F8E};     /** value */private double[] mvalues;    /** value converted to an angle */private float[] mangles;      /** Pie chart Diameter */private float PieR;            /** the total angle of pie chart */private float pieangle; Private string[] mtitles; The contents of each section are private String memptymsg = "no data"; No hint of content private float mtitlesize;private float mvaluesize;/** the size of the text inside the pie chart */private float Mpietextsize;private int Mtitlecolor = 0xff595959;private int mvaluecolor = 0xff595959;private int mdefaultpointcolor = 0xfff5a002; Mtextbound;private Paint mtextpaint;private Paint mpiepaint;public piechart (context context), the color of the text when prompted by countless data {This (context,null);} Public Piechart (context context, AttributeSet Attrs) {This (context, attrs,0);} Public Piechart (context context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr); mtitlesize = SP2PX (Mpietextsiz);E = sp2px (n); mvaluesize = sp2px (+); mpiepaint = new Paint (); mtextpaint = new Paint (); mtextbound = new Rect (); Mtextpaint.s Etcolor (0xff595959); mtextpaint.settextsize (mtitlesize);} @Overrideprotected void OnDraw (canvas canvas) {super.ondraw (canvas); Mpiepaint.setantialias (true); Mtextpaint.setantialias (true);/**------------------------------No Data--------------------------------*/if (mtitles = = NULL | | Mtitles.length = = 0 | | Isvalueempty ()) {Mpiepaint.setcolor (Mdefaultpointcolor); Mtextpaint.setcolor (0xFFFFFFFF); float cr = (getwidth () < GetHeight ()? GetWidth ()/2:getheight ()/2)-Lr_padding;canvas.drawcircle (GetWidth ()/2, GetHeight ()/2, CR, Mpiepaint); Mtextpaint.gettextbounds (memptymsg, 0, Memptymsg.length (), mtextbound); Canvas.drawtext (Memptymsg, (GetWidth ()- Mtextbound.width ())/2, (GetHeight () +mtextbound.height ())/2, mtextpaint); return;} /**------------------------------No data--------------------------------*//**------------------------------ appeased Figure--------------------------------*/int textHeight = GetteXtheight ("xx", Math.max (Mtitlesize, mvaluesize)); float R1 = getwidth ()-Lr_padding*2;float r2 = getheight ()-top_padding -Pie_text_dis-(text_text_dis+textheight) * (mtitles.length)-bottom_dis;pier = Math.min (r1, R2);//To prevent the pie chart from overstepping, Pie chart Diameter Select the minimum value RECTF oval = new RECTF ((GetWidth ()-pier)/2, top_padding, (GetWidth () +pier)/2, top_padding+pier); Mpiepaint.setstyle (Paint.Style.FILL); mangles = Getangles (); Float startangle = 0;for (int i=0;i<mangles.length;i++) {Mpiepaint.setcolor (mcolors[i]), if (mangles[i] = = 0) Continue;canvas.drawarc (Oval, StartAngle, Mangles[i], True, Mpiepaint); StartAngle + = (Mangles[i]+angle_dis);} /**------------------------------appeased Figure--------------------------------*//**------------------------------The bottom of the text, Title and value--------------------------------*/float CR = 5 * density; Dot radius float CTD = 8 * density; Dot and right text distance float Titlelen = getmaxtextwidth (Mtitles, mtitlesize) + title_value_dis;float len = 2*cr + ctd + Titlelen + get Maxtextwidth (Mvalues, mvaluesize); float Topdis = top_pADDING + Pie_text_dis +pier + textHeight; The first line of text at the bottom and the top of the control is float CX = (getwidth ()-len)/2+cr;float Titlex = cx+cr+ctd;float Valuex = Titlex + Titlelen;int Valuelen = mvalues.length-1;for (int i=0;i<mtitles.length;i++) {mpiepaint.setcolor (mcolors[i]); float Ydis = topDis+ ( Textheight+text_text_dis) *i;canvas.drawcircle (CX, YDIS-TEXTHEIGHT/2, CR, Mpiepaint); Mtextpaint.settextsize ( mtitlesize); Mtextpaint.setcolor (Mtitlecolor); Canvas.drawtext (Mtitles[i], Titlex, Ydis, Mtextpaint); Mtextpaint.setcolor (Mvaluecolor); mtextpaint.settextsize (mvaluesize); Canvas.drawtext (AmountUtils.moneyFormat (i >valuelen?0:mvalues[i]), Valuex, Ydis, mtextpaint);} /**------------------------------The bottom text, title and value--------------------------------*///the text on the pie chart Setpiecontenttext (canvas);} /** * Set each pie chart to represent the name * @param titles */public void Settitles (list<string> titles) {Mtitles = (string[]) Titles.toarray () ;} /** * Set the name of each pie chart represented by * @author Huangyuguang * Create on December 30, 2015 * @param titles */public void Settitles (string[] TitLes) {mtitles = titles;} /** * Set Value * @param values */public void setvalues (list<double> values) {mvalues = new double[values.size ()];for (int i =0;i<values.size (); i++) {Mvalues[i] = Values.get (i);}} /** * Set Value * @param values */public void Setvalues (double[] values) {mvalues = values;} /** * Set the color of each pie chart * @param colors */public void setcolors (list<integer> colors) {mcolors = new int[colors.size ()];for (i NT I=0;i<colors.size (); i++) {Mcolors[i] = Colors.get (i);}} /** * Set the color of each pie chart * @param colors */public void setcolors (int[] colors) {mcolors = colors;} /** * Sets the font size of the name * @param size */public void settitlesize (float size) {mtitlesize = sp2px (size);} /** * Sets the size of the numeric value * @param size */public void setvaluesize (float size) {mvaluesize = sp2px (size);} /** * Set the size of the text on the pie chart * @param size */public void setpietextsize (float size) {mpietextsize = sp2px (size);} /** * Name color * @param titlecolor */public void settitlecolor (int titlecolor) {mtitlecolor = Titlecolor;} /** * Number of colors * @param valuecolor */public void SetValueColor (int valuecolor) {mvaluecolor = Valuecolor;} /** * Set the color of the hint text when no data * Create on December 31, 2015 * @param color */public void setdefaultpointcolor (int color) {Mdefaultpointcolo R = Color;} /** * No data hint content * @param msg */public void Setemptymsg (String msg) {memptymsg = msg;} Private Boolean Isvalueempty () {if (mvalues = = NULL | | mvalues.length = = 0) return true;for (double va:mvalues) {if (Va > 0) return false;} Memptymsg = "no data"; return true;}  /** * Get the angle of each value * @return */private float[] Getangles () {if (mvalues = null | | mvalues.length = 0) return null;double sum = 0;int len = mtitles.length;float[] angles = new Float[len];int Gapcount = 0;//pie gap bar number for (int i=0;i<len;i++) {sum + = MV Alues[i];if (mvalues[i]>0) gapcount++;} float angle = 0;pieangle = 360-gapcount*angle_dis;for (int i=0;i<len-1;i++) {Angles[i] = (float) (pieangle*mvalues[i]/ sum); angle + = Angles[i];} if (mvalues[len-1]>0) angles[len-1] = Pieangle-angle;return angles; }/** * Write a percentage on each pie in the pie chart and must be placed after calculating the angle of each value angles * @param canvas */private void Setpiecontenttext (canvas canvas) {Float pre = 0;float[] Centerangle = new Float[mangles.length];for (int i=0;i&lt ; mangles.length;i++) {if (mangles[i] = = 0) Continue;centerangle[i] = ANGLE_DIS+MANGLES[I]/2 + Pre;pre + = MAngles[i];} float Cenr = pier*1.0f/2*3/5;float Lastpir = 1.0f;//in order to make all the% ratios equal to 1mtextpaint.setcolor (0xFFFFFFFF); float Cenx = 0;float ceny = 0;for (int i=0;i<centerangle.length;i++) {if (centerangle[i]==0) continue;float xa = (float) (CENR * Math.cos (CEN Terangle[i] (math.pi/180)); float ya = (float) (CENR * Math.sin (centerangle[i] * (math.pi/180))); Cenx = GetWidth () * * .0f/2+xa;ceny = top_padding + PIER*1.0F/2 + ya;mtextpaint.settextsize (mpietextsize);d ouble curPer = numDecimals (mAngles [I]/pieangle]; String permsg = I==centerangle.length-1?percentformat (lastpir):p Ercentformat (curper); Canvas.drawtext (PERMSG, Cenx-gettextwidth (permsg, mpietextsize) *1.0F/2, Ceny+gettextheight (permsg, mpietextsize) *1.0F/2/2, mTextPaint); Lastpir-= Curper;}} private int Getmaxtextwidth (dOuble[] ds,float size) {string[] STRs = new string[ds.length];for (int i=0;i<ds.length;i++) {Strs[i] = Amountutils.moneyformat (Ds[i]);} Return Getmaxtextwidth (STRs, size);} private int getmaxtextwidth (string[] strs,float size) {rect textbound = new Rect (); Paint paint = new paint ();p aint.settextsize (size), int len = 0;for (int i=0;i<strs.length;i++) {paint.gettextbounds ( Strs[i], 0, Strs[i].length (), textbound), Len = Math.max (len, Textbound.width ());} return Len;} private int Gettextwidth (String str,float size) {return gettextrect (str, size). width (); private int Gettextheight (String str,float size) {return gettextrect (str, size). Height (); Private Rect Gettextrect (String str,float size) {Rect textbound = new Rect (); Paint paint = new paint ();p aint.settextsize (size);p aint.gettextbounds (str, 0, Str.length (), textbound); return Textbound;} Private float sp2px (float sp) {return typedvalue.applydimension (typedvalue.complex_unit_sp, SP, getresources (). Getdisplaymetrics ());} /** * Formatted as percent format * @param num * @rEturn */private String percentformat (double num) {DecimalFormat df = new DecimalFormat ("#0.00%"); return Df.format (num);} /** * Reserved Four decimal places * @param num * @return */public static double numdecimals (double num) {return ((int) (num*10000)) *1.0d/10000;} }


pie chart Control Download


Android Piechart Pie Chart control

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.