The project recently used a variety of charts, originally intended to use a third party, such as Mpandroid, this is a very powerful chart library, the application is very convenient, but finally found and design is not the same, no way, can only write their own. Today will be a written column of the demo posted here, the histogram can be based on the function of the data a few points:
1. According to the number of data, the dynamic plot of the pillars of the column chart;
2. Column chart each pillar of the drawing has a dynamic animation effect;
3. Each pillar has the Click event, when clicked Pop-up Prompt box, displays the related information, stipulated time, the pop-up window automatically disappears.
Okay, let's go ahead and show you the chart:
The following code is posted below:
Custom Column Chart classes:
Package Com.example.histogram;
Import Android.content.Context;
Import Android.graphics.Canvas;
Import Android.graphics.Color;
Import Android.graphics.Paint;
Import Android.graphics.RectF;
Import Android.os.Handler;
Import Android.text.TextPaint;
Import Android.util.AttributeSet;
Import Android.util.Log;
Import android.view.MotionEvent;
Import Android.view.View;
Import Com.example.histogram.UI.UI;
Import Java.text.NumberFormat;
/** * Created by Zhangzdon 2016/6/16 0016. * Histogram/public class histogram extends View implements Runnable {private Handler Handler = new Handler (); New, realize animation private float animheight; Progress bar Animation height private Paint axislinepaint; Axis brushes private Paint hlinepaint; Internal horizontal dashed brush private Paint textpaint; Draw the text brush private Paint recpaint; Draws a histogram of the shadow background of a columnar chart private Paint datapaint; Draw the pen of the bar chart private Paint TextPaint2; Draw White text brush private Paint textPaint3; Draw the coordinates of the brush private Paint textPaint4; Draw the white vertical line on the x axis of the brush PRIVate string[] xtitlestring; X-axis scale private string[] ytitlestring; Y-axis scale private string[] data; The interface returns the Indicatordata used to compute the column height NumberFormat numberformat; Used to format the digital private float currentheight; The height of the current histogram should be computed by the private int num =-1;
How many columns to draw, because there are just boot data less than 24 of the case private float mrelativepxinheight;
private float mrelativepxinwidth;
Private Onchartclicklistener listener;
private int mdist;
public void setnum (int num) {this.num = num;
Invalidate ();
public void SetData (string[] data) {this.data = data;
Invalidate ();
public void Setxtitlestring (string[] title) {this.xtitlestring = title;
Invalidate ();
The public histogram {This (context, NULL);
Public histogram (context, AttributeSet attrs) {This (context, attrs, 0);
public void Settitle (string[] title) {this.xtitlestring = title; Public histogram, AttributeSet attrs, int defstyLEATTR) {Super (context, attrs, defstyleattr);
Init (context, attrs); /** * For related initialization * @param context * @param attrs/private void init, AttributeSet
Attrs) {axislinepaint = new Paint ();
Hlinepaint = new Paint ();
Textpaint = new Paint ();
Recpaint = new Paint ();
Datapaint = new Paint ();
TextPaint2 = new Paint ();
TextPaint3 = new Paint ();
TextPaint4 = new Paint ();
NumberFormat = Numberformat.getnumberinstance (); Numberformat.setminimumfractiondigits (3); Set to retain three decimal axislinepaint.setcolor (Color.parsecolor ("#dbdde4") when printing;
Set the axis color to white Hlinepaint.setargb (51, 255, 255, 255);
Textpaint.setcolor (Color.parsecolor ("#8593a1"));
Textpaint.settextsize (29);
Textpaint.settextsize (ui.dip2px (GetContext (), 12));
Recpaint.setcolor (Color.parsecolor ("#f2f5fc"));
Datapaint.setcolor (Color.cyan);
Textpaint2.setcolor (Color.White); Textpaint2.settextsize (Ui.dip2PX (GetContext (), 12));
Textpaint3.setcolor (Color.parsecolor ("#000000"));
Textpaint3.settextsize (ui.dip2px (GetContext (), 9));
Textpaint4.setcolor (Color.parsecolor ("#8593a1"));
Textpaint4.settextsize (ui.dip2px (GetContext (), 6));
Axislinepaint.setantialias (TRUE);
Hlinepaint.setantialias (TRUE);
Textpaint.setantialias (TRUE);
Recpaint.setantialias (TRUE);
Datapaint.setantialias (TRUE);
Textpaint2.setantialias (TRUE);
Textpaint3.setantialias (TRUE);
Textpaint4.setantialias (TRUE);
} @Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas);
if (data = null | | xtitlestring = NULL | | | num < 0) {return;
///Draw Y-axis scale paint.fontmetrics metrics = textpaint3.getfontmetrics ();
int decent = (int) metrics.descent;
Float width = getwidth ();
float height = getheight ();
According to the prototype diagram, the relative dimensions of each px height in the figure mrelativepxinheight = height/470; According to the prototype diagram, the relative dimensions of each px width in the picture are shown in the actual figure MRElativepxinwidth = width/690;
Textpaint3.settextalign (Paint.Align.RIGHT);
Draw Ordinate ytitlestring = new string[6];
YTITLESTRING[5] = "0";
YTITLESTRING[4] = "20";
YTITLESTRING[3] = "40";
YTITLESTRING[2] = "60";
YTITLESTRING[1] = "80";
Ytitlestring[0] = "100"; for (int i = 0; i < ytitlestring.length i++) {canvas.drawtext (ytitlestring[i), Mrelativepxinwidth, (72 +
I *) * mrelativepxinheight + decent, textPaint3);
//Draw X-axis scale textpaint3.settextalign (Paint.Align.CENTER);
Textpaint4.settextalign (Paint.Align.CENTER);
Textpaint textpaint = new Textpaint ();
Textpaint.setcolor (Color.parsecolor ("#000000"));
Textpaint.settextsize (ui.dip2px (GetContext (), 9));
Compute the spacing between columns//leftmost position mrelativepxinwidth, the rightmost position 630 epxinwidth, float totalwidth = 630-100;
The spacing between the pillar and the child is mdist = (int) (Totalwidth/(xtitlestring.length + 1)); for (int i = 0; i < xtitlestring.length; i++) {//Draw white vertical canvas.drawline ((i+1) * mdist) * mrelativepxinwidth, 348 * mrelativepxinheight, (100 + (
i+1) * mdist) * mrelativepxinwidth, 352 * mrelativepxinheight, axislinepaint); Draw x-axis text Canvas.drawtext (Xtitlestring[i], (+ (i+1) * mdist) * mrelativepxinwidth, 370 * mrelativepxinheight, TE
XTPAINT3);
//Draw Rectangle shadow for (int i = 0; i < num; i++) {RECTF RECTF = new RECTF ();
Rectf.left = relativepxinwidth + i * relativepxinwidth;
Rectf.right = 121 * Relativepxinwidth + i * relativepxinwidth;
Rectf.left = Mrelativepxinwidth + (i+1) * mdist * mrelativepxinwidth;
Rectf.right = Mrelativepxinwidth + (i+1) * mdist * mrelativepxinwidth;
Rectf.top = Mrelativepxinheight;
Rectf.bottom = 338 * mrelativepxinheight;
Canvas.drawroundrect (RECTF, ten, recpaint); //Draw the X-axis coordinate for (int i = 0; i < 6; i++) {Canvas.drawline * MrelaTivepxinwidth, (+ i *) * mrelativepxinheight + decent, 630 * mrelativepxinwidth, (+ i *) * mrelativepxinheight
+ decent, axislinepaint); //delay drawing to achieve animation effect.
The larger the number, the longer the delay, the slower the animation effect will be handler.postdelayed (this, 1);
for (int i = 0; i < num i++) {RECTF DATARECTF = new RECTF ();
Datarectf.left = Mrelativepxinwidth + (i + 1) * mdist * mrelativepxinwidth;
Datarectf.right = Mrelativepxinwidth + (i + 1) * mdist * mrelativepxinwidth;
Datapaint.setcolor (Color.parsecolor ("#3ac2d9"));
Get column Height currentheight = float.parsefloat (Data[num-1-i]);
if (Currentheight = = 0) {datarectf.top = 346 * mrelativepxinheight;
else if (currentheight = =) {datarectf.top = * mrelativepxinheight; else {if (animheight >= currentheight) {datarectf.top = 346 * Mrelativepxinheight-currentheig
HT/100 * 276 * mrelativepxinheight; else {DATARECTF. top = 346 * mRelativePxInHeight-276 * mrelativepxinheight * (animheight/100);
} datarectf.bottom = 346 * mrelativepxinheight; Limit Maximum height if (Datarectf.top < mrelativepxinheight) {datarectf.top = * Mrelativepxinheig
Ht
Canvas.drawroundrect (DATARECTF, datapaint);
}//The animation effect of column growth @Override public void Run () {animheight = 1;
if (animheight >= 276 * mrelativepxinheight) {return;
else {invalidate (); @Override public boolean ontouchevent (Motionevent event) {switch (event.getaction ()) {Case Moti
Onevent.action_down: {//get click coordinate float x = Event.getx ();
Float y = event.gety ();
To judge the location of the click Point float leftx = 0;
float rightx = 0; for (int i = 0; i < num i++) {LEFTX = Mrelativepxinwidth + (i+ 1) * Mdist * Mrelativepxinwidth-mdis T/2 * MrelativepxinWidth;
RIGHTX = Mrelativepxinwidth + (i+ 1) * mdist * mrelativepxinwidth + MDIST/2 * mrelativepxinwidth;
if (x < LEFTX) {continue; } if (Leftx <= x && x <= rightx) {//Get the Y-value of the clicked column area float top = 346 * mRe
Lativepxinheight-float.parsefloat (Data[num-1-i])/276 * mrelativepxinheight;
Float bottom = 346 * mrelativepxinheight; if (y >= top && y <= bottom) {//Decide whether to set up the listening///will click on the first few pillars, click on the pillar at the tops of the Sit value for pop-up dialog hint data , also returns a percentage currentheidht = float.parsefloat (Data[num-1-i)) if (listener!= null) {LOG.E ("
SS "," X "+ x +"; y: "+ y);
Listener.onclick (i + 1, leftx + mdist/2,top,float.parsefloat (data[num-1-i)));
} break;
}} break; Case MOTIONEVENT.ACTION_MOVE:LOG.E ("Touch", "ACtion_move ");
Break
Case MOTIONEVENT.ACTION_UP:LOG.E ("Touch", "action_up");
Break
return true; /** * Post click on the Listener interface/public interface Onchartclicklistener {void onClick (int num, float x, float y, F
Loat value); /** * Set pillar Click to monitor the method * @param listener/public void Setonchartclicklistener (Onchartclicklistener listen
ER) {this.listener = listener; }
}
Applications in XML files:
<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android=
"http://schemas.android.com/" Apk/res/android "
xmlns:tools=" Http://schemas.android.com/tools "
android:id=" @+id/activity_main
" Android:layout_width= "Match_parent"
android:layout_height= "match_parent"
android:orientation= "vertical" "
tools:context=" com.example.histogram.MainActivity ">
<textview
android:layout_width=" match _parent "
android:layout_height=" 40DP "
android:gravity=" center "
android:text=" busy indicator chart (%)
Android:textsize= "15SP"
android:textcolor= "#000000"
/>
<com.example.histogram.histogram
android:id= "@+id/staticview"
android:layout_width= "400DP"
android:layout_height= "500DP"
Android:layout_gravity= "Center_horizontal"
android:layout_marginbottom= "14DP"
android:layout_ margintop= "5DP"/>
implementation in activity:
Package Com.example.histogram;
Import Android.os.Bundle;
Import Android.os.Handler;
Import android.support.v7.app.AppCompatActivity;
Import Android.util.Log;
Import Android.view.View;
Import Android.widget.PopupWindow;
Import Android.widget.TextView;
public class Mainactivity extends Appcompatactivity {private Popupwindow Mpopupwindow;
@Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
Setcontentview (R.layout.activity_main);
Final histogram histogram = (histogram) Findviewbyid (R.id.staticview);
string[] Data ={"100", "20", "40", "20", "80", "20", "60", "30", "5", "20", "60", "30", "5", "5", "20", "60", "30", "5"};
Final string[] title = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "6", "7", "8", "9", "9", "6", "7", "8", "9"};
Histogram.setnum (title.length);
Histogram.setdata (data);
Histogram.setxtitlestring (title);
Histogram.setonchartclicklistener (New Histogram.onchartclicklistener () {@Override public void OnClick (int num, float x, float y, float value) {//Show hint window View inflate = view.inflate (Mai
Nactivity.this, R.layout.popupwindow, NULL);
TextView TextView = (TextView) Inflate.findviewbyid (R.ID.MAIN_TV);
Textview.settext (value + "%\n" + title[num-1]);
if (Mpopupwindow!= null) {Mpopupwindow.dismiss ();
} Mpopupwindow = new Popupwindow (inflate,140, true);
Mpopupwindow.settouchable (TRUE);
LOG.E ("ss", "num" + num +); X "+ x+"; y "+ y +"; value "+ Value +";(int) ((-histogram.getheight ()) + y-65) "
+ (int) ((-histogram.getheight ()) + y-65) + "histogram.getheight ()" + histogram.getheight ()); Set the parameters and then show//Toast.maketext (mainactivity.this, "num" + num + "; x" + x+ "; y" + y + "; value" + Value// + ";p opupwindow.getwidth ()" + mpopupwindow.getwidth () + ";"
+ Mpopupwindow.getheight (), Toast.length_short). Show (); MpopupwindoW.showasdropdown (histogram, (int) (X-65), (int) ((-histogram.getheight ()) + y-65));
Mpopupwindow.setbackgrounddrawable (Getresources (). getdrawable (r.mipmap.databg_busyness));
New Handler (). postdelayed (New Runnable () {public void run () {Mpopupwindow.dismiss ();
}, 1000);
}
}); }
}
The above is a histogram of the Android custom with growth animation and click on the Bullet window tip effect. To achieve a simulated background data login effect, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!