Android: Use Canvas to plot column charts (automatically calculate width and degree values, swipe left and right)

Source: Internet
Author: User
Tags drawtext float max

This example implements a simple columnar chart, as follows:


Characteristics:

1. Automatically calculates the height, width, and spacing of each entry according to the data source, automatically calculating the value of the degree.

2. When the number of entries, you can swipe left and right to see the whole content, graphics, text synchronization sliding, and let go after the gradual stop (rather than immediately stop).


Code:

(1) Core code: Barchartview.java

Package Com.sina.appbarchart;import Android.app.activity;import Android.content.context;import Android.graphics.bitmap;import Android.graphics.bitmapfactory;import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.paint;import Android.graphics.path;import Android.graphics.Rect; Import Android.support.annotation.nonnull;import Android.support.v7.app.actionbar;import Android.support.v7.app.actionbaractivity;import Android.util.attributeset;import Android.view.MotionEvent;import android.view.view;/** * Custom components: Bar chart * Created by Hanj on 14-12-30.    */public class Barchartview extends View {private int screenw, screenh;    Private barchartitembean[] Mitems;    Max value in Mitems.    private float MaxValue;    Max height of the bar private int maxheight;    Private int[] Mbarcolors = new int[]{color.red, Color.green, Color.Blue, Color.yellow, Color.magenta, Color.CYAN};    Private Paint Barpaint, Linepaint, Textpaint; Private Rect Barrect, Leftwhiterect, Rightwhiterect;    Private Path Textpath;    private int LeftMargin, TopMargin, Smallmargin;    The width of one bar item private int baritemwidth;    The spacing between.    private int barspace;    The width of the line.    private int linestrokewidth;     /** * The x-position of Y-index and the y-position of the X-index.    */Private float x_index_starty, y_index_startx;    Private Bitmap arrowbmp;    Private Rect x_index_arrowrect, Y_index_arrowrect;    private static final int bg_color = Color.parsecolor ("#E5E5E5");        Public Barchartview (context context, AttributeSet Attrs) {Super (context, attrs);    Init (context);        } private void Init (context context) {Screenw = Screenutils.getscreenw (context);        Screenh = screenutils.getscreenh (context);        LeftMargin = screenutils.dp2px (context, 16);        TopMargin = screenutils.dp2px (context, 40);        Smallmargin = screenutils.dp2px (context, 6); Barpaint = new PaiNT ();        Barpaint.setcolor (Mbarcolors[0]);        Linepaint = new Paint ();        Linestrokewidth = screenutils.dp2px (context, 1);        Linepaint.setstrokewidth (Linestrokewidth);        Textpaint = new Paint ();        Textpaint.setantialias (TRUE);        Barrect = new Rect (0, 0, 0, 0);        Textpath = new Path ();        Leftwhiterect = new Rect (0, 0, 0, screenh);        Rightwhiterect = new Rect (screenw-leftmargin, 0, Screenw, screenh);    Arrowbmp = Bitmapfactory.decoderesource (Context.getresources (), r.drawable.arrow_up);    }//The flag has acquired the height of the state pull private Boolean statusheighthasget;        @Override protected void OnDraw (canvas canvas) {super.ondraw (canvas);            if (!statusheighthasget) {substatusbarheight ();        Statusheighthasget = true;        }//draw background Canvas.drawcolor (Bg_color);        Bounds checkleftmoving ();        Textpaint.settextsize (screenutils.dp2px (GetContext (), 16)); for (int i = 0; i < Mitems.length;  i++) {//draw bar rect barrect.left = (int) Y_index_startx + baritemwidth * i + barspace * (i + 1)-            (int) leftmoving;            Barrect.top = TopMargin * 2 + (int) (MaxHeight * (1.0f-mitems[i].itemvalue/maxvalue));            Barrect.right = Barrect.left + baritemwidth;            Barpaint.setcolor (mbarcolors[i% mbarcolors.length]);            Canvas.drawrect (Barrect, barpaint);            Draw Type text String TypeText = Mitems[i].itemtype; Float Textpathstartx = barrect.left + BARITEMWIDTH/2-(float) (Math.sin (MATH.PI/6)) * textpaint.me            Asuretext ("good")/2;            float textpathstarty = Barrect.bottom;            Textpath.reset ();            Textpath.moveto (Textpathstartx, Textpathstarty);            Textpath.lineto (Textpathstartx + (float) ($ * Math.tan (MATH.PI/6)), Textpathstarty + 1000); Canvas.drawtextonpath (TypeText, Textpath, Smallmargin * 1.5f, Smallmargin * 2, TExtpaint);            Draw Value text String ValueText = string.valueof (Mitems[i].itemvalue); Canvas.drawtext (ValueText, Barrect.left-(Textpaint.measuretext (ValueText)-baritemwidth)/2, Barrec        T.top-smallmargin, Textpaint);        }//draw left white space and right white space int c = Barpaint.getcolor ();        Barpaint.setcolor (Bg_color);        Leftwhiterect.right = (int) y_index_startx;        Canvas.drawrect (Leftwhiterect, barpaint);        Canvas.drawrect (Rightwhiterect, barpaint);        Barpaint.setcolor (c);        Draw X-index Line. Canvas.drawline (Y_INDEX_STARTX-LINESTROKEWIDTH/2, X_index_starty, screen        W-leftmargin, X_index_starty, Linepaint);        Draw Y-index Line. Canvas.drawline (Y_index_startx, X_index_starty + LINESTROKEWIDTH/2, Y_inde X_startx, TOPMARGIN/2, Linepaint);        Canvas.drawbitmap (arrowbmp, NULL, y_index_arrowrect, NULL);        Canvas.save (); Canvas.rotate (X_index_arrowrect.left + x_index_arrowrect.right)/2, (X_index_arrowrect.top + x_index_        Arrowrect.bottom)/2);        Canvas.drawbitmap (arrowbmp, NULL, x_index_arrowrect, NULL);        Canvas.restore ();        Draw Division Value int maxdivisionvalueheight = (int) (MaxHeight * 1.0f/maxvalue * maxdivisionvalue);        Textpaint.settextsize (screenutils.dp2px (GetContext (), 10));            for (int i = 1; i <=; i++) {Float starty = barrect.bottom-maxdivisionvalueheight * 0.1f * i;            if (Starty < TOPMARGIN/2) {break;            } canvas.drawline (Y_index_startx, starty, Y_index_startx + ten, starty, Linepaint);            String Text = string.valueof (Maxdivisionvalue * 0.1f * i); Canvas.drawtext (text, Y_index_startx-textpaint.measuretext (Text)-5, Starty + textpaint.measuretext ("0")/2, textpaint);    }} private float leftmoving;    private float Lastpointx;    private float movingleftthistime = 0.0f;        @Override public boolean ontouchevent (@NonNull motionevent event) {int type = Event.getaction ();                Switch (type) {Case MotionEvent.ACTION_DOWN:lastPointX = event.getrawx ();            Break                Case MotionEvent.ACTION_MOVE:float x = event.getrawx ();                Movingleftthistime = Lastpointx-x;                Leftmoving + = Movingleftthistime;                Lastpointx = x;                Invalidate ();            Break Case MOTIONEVENT.ACTION_UP://smooth scroll new Thread (New Smoothscrollthread (movingleftthis                Time). Start ();            Break        Default:return super.ontouchevent (event);    } return true; }   /** * Check The value of leftmoving to ensure, the view is not an out of the.        */private void checkleftmoving () {if (leftmoving < 0) {leftmoving = 0;        } if (Leftmoving > (maxright-minright)) {leftmoving = Maxright-minright;    }} public barchartitembean[] GetItems () {return mitems; public void Setitems (barchartitembean[] items) {if (items = = null) {throw new RuntimeException ("B        Archartview.setitems (): The Param items cannot be null. ");        if (Items.length = = 0) {return;        } this.mitems = items;        Calculate the max value.        MaxValue = Items[0].itemvalue; for (Barchartitembean bean:items) {if (Bean.itemvalue > MaxValue) {maxValue = Bean.itemva            Lue        }}//calculate the Max division value.        GetRange (maxValue, 0);    Get the width of each bar.    Getbaritemwidth (Screenw, items.length);        Refresh the view.    Invalidate ();    } private int maxright, minright;     /** * Get the width of each bar which are depended on the SCREENW and item count.        */private void getbaritemwidth (int screenw, int itemCount) {//the min width of the bar is 50DP.        int minbarwidth = screenutils.dp2px (GetContext (), 40);        The min width of spacing.        int minbarspacing = screenutils.dp2px (GetContext (), 30);        Baritemwidth = (Screenw-leftmargin * 2)/(ItemCount + 3);        Barspace = (Screenw-leftmargin * 2-baritemwidth * itemCount)/(ItemCount + 1);            if (Baritemwidth < Minbarwidth | | Barspace < minbarspacing) {baritemwidth = Minbarwidth;        Barspace = minbarspacing;        } maxright = (int) Y_index_startx + linestrokewidth + (barspace + baritemwidth) * MITEMS.LENGTH;    Minright = Screenw-leftmargin-barspace; }/** * Sub the height of Status bar and action Bar to get the accurate height of screen. */private void Substatusbarheight () {//the height of the status bar int statusheight = Screenutils.gets        Tatusbarheight (Activity) getcontext ());        The height of the actionBar actionBar ab = ((actionbaractivity) GetContext ()). Getsupportactionbar (); int abheight = AB = = null?        0:ab.getheight ();        Screenh-= (statusheight + abheight);        Barrect.top = TopMargin * 2;        Barrect.bottom = Screenh-topmargin * 3;        MaxHeight = Barrect.bottom-barrect.top;        X_index_starty = Barrect.bottom; X_index_arrowrect = new Rect (screenw-leftmargin, (int) (X_INDEX_STARTY-10), Screenw-leftmargin + 10, (int)    (X_index_starty + 10));    }//the Max and Min division value.    Private float maxdivisionvalue, mindivisionvalue;    Get the max and Min division value by the max and Min value in Mitems. private void GetRange (float maxValue, floatMinValue) {//max int scale = Utility.getscale (MaxValue);        float Unscaledvalue = (float) (Maxvalue/math.pow (ten, scale));        Maxdivisionvalue = (float) (Getrangetop (unscaledvalue) * MATH.POW (scale));        Y_index_startx = Getdivisiontextmaxwidth (maxdivisionvalue) + 10; Y_index_arrowrect = new Rect ((int) (Y_INDEX_STARTX-5), TOPMARGIN/2-A, (int) (Y_INDEX_STARTX + 5), to    PMARGIN/2);        } private float Getrangetop (float value) {//value: [1,10) if (value < 1.2) {return 1.2f;        } if (value < 1.5) {return 1.5f;        } if (value < 2.0) {return 2.0f;        } if (value < 3.0) {return 3.0f;        } if (value < 4.0) {return 4.0f;        } if (value < 5.0) {return 5.0f;        } if (value < 6.0) {return 6.0f; } if (value < 8.0) {return 8.0F    } return 10.0f;     }/** * Get the max width of the division value text.        */Private float getdivisiontextmaxwidth (float maxdivisionvalue) {Paint textpaint = new Paint ();        Textpaint.settextsize (screenutils.dp2px (GetContext (), 10));        float max = Textpaint.measuretext (string.valueof (Maxdivisionvalue * 0.1f)); for (int i = 2; I <=; i++) {Float w = textpaint.measuretext (string.valueof (maxdivisionvalue * 0.1f * i))            ;            if (W > max) {max = W;    }} return max;     }/** * Use this thread to the create a smooth scroll after action_up.        */Private class Smoothscrollthread implements Runnable {float lastmoving;        Boolean scrolling = true;            Private Smoothscrollthread (float lastmoving) {this.lastmoving = lastmoving;        scrolling = true;         } @Override public void Run () {while (scrolling) {       Long start = System.currenttimemillis ();                lastmoving = (int) (0.9f * lastmoving);                Leftmoving + = lastmoving;                Checkleftmoving ();                Postinvalidate ();                if (Math.Abs (lastmoving) < 5) {scrolling = false;                } Long end = System.currenttimemillis ();                    if (End-start <) {try {thread.sleep (end-start));                    } catch (Interruptedexception e) {e.printstacktrace ();     }}}}/** * A model class to keep the bar item info.        */Static class Barchartitembean {private String itemType;        private float Itemvalue;            Public Barchartitembean (String itemType, float itemvalue) {this.itemtype = ItemType;        This.itemvalue = Itemvalue; }    }}
(2) Use of this custom component:

Package Com.sina.appbarchart;import Android.support.v7.app.actionbaractivity;import Android.os.bundle;public class Mainactivity extends Actionbaractivity {@Override protected void onCreate (Bundle savedinstancestate) {Super        . OnCreate (Savedinstancestate);        Setcontentview (R.layout.activity_main);        Barchartview Barchartview = (barchartview) Findviewbyid (R.id.bar_chart); barchartview.barchartitembean[] items = new barchartview.barchartitembean[]{new BARCHARTVIEW.BARCHARTITEMB EAN ("Food and Beverage"), New Barchartview.barchartitembean ("Learning", "Max"), New BARCHARTVIEW.BARCHARTITEMB EAN ("Travel", +), new Barchartview.barchartitembean ("shopping"), new BARCHARTVIEW.BARCHARTITEMB EAN ("interpersonal", Barchartview.barchartitembean), New ("Entertainment,"), New Barchartview.barchartitem        Bean ("Investment", "Barchartview.barchartitembean"), New ("Education", 280)}; Barchartview.setItems (items); }}

================

Source Download (Free points Oh!) ):

http://download.csdn.net/detail/books1958/8386035



Android: Use Canvas to plot column charts (automatically calculate width and degree values, swipe left and right)

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.