android自定義統計折線圖和柱狀圖組合
阿新 • • 發佈:2019-01-10
本程式碼是一年前公司專案需要自己所寫,當時做android專案需要統計的功能,統計的圖表包括餅圖、柱狀圖、折線圖,程式碼寫的有些笨拙!希望大家能夠看懂!其程式碼做拋磚引玉,希望大家能夠再改寫下!可以用多執行緒做出動畫,是不是更好呢?這些後期我也沒有整理過,所以誰能再整理下!此含有柱狀圖和折線圖的組合,有興趣的可以拆分成單個的折線圖和柱狀圖。
LineHistogram.java
package com.wforyou.dhh.ui.widget; import java.util.Arrays; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.view.View; import android.view.View.MeasureSpec; public class LineHistogram extends View { private int mAscent; private String mText=""; // 螢幕的高度 public static int heightPixels = 0; // 螢幕的寬度 public static int widthPixels = 0; // X軸 public static float XLength = 600.f; // Y軸 public static float Ylength = 300.0f; // X軸最大值 public static float XMAXLENGTH = 2500.0f; // Y軸最大值 public static float YMAXLENGTH = 250.0f; // 畫筆 private static Paint paint; // 距離螢幕左邊的距離 private static float marginleft = 0; // 距離螢幕上邊的距離 private static float margintop = 0; // 統計圖的標題 public String NoteText = ""; // 實際提示資訊 public String thinkNoteText = ""; // 計劃提示資訊 public String realityNoteText = ""; // 平均刻度值 public static int average = 40; // y軸刻度的平均值,需要幾個刻度 public static int yaverage = 6; // 以多少畫素取幾個刻度 public static float faverage = 50; // x軸刻度的間距 public static float xaverage = 40; /**文字資訊**/ public String[] ValuesText = { "褲子", "文胸", "T恤", "襯衣", "保暖衣", "保暖褲", "頭巾", "圍巾" }; /**計劃所對應的金額**/ public double[] thinkValues = { 360, 400, 600, 2000, 1500, 485, 315, 365 }; /**實際所對應的金額**/ public double[] realityValues = { 300, 180, 150, 180, 900, 35, 255, 125 }; /**計劃金額的顏色**/ public static int thinkcolor = Color.parseColor("#004882"); /**實際金額的顏色**/ public static int truecolor = Color.parseColor("#C96118"); /**平均刻度值與實際刻度值的比**/ public static float xpaverage = 1; /**Y軸提示資訊**/ public static String yText="金額"; /**x軸提示資訊**/ public static String xText=""; /**文字資訊的間距**/ public static float yspace=60; public LineHistogram(Context context, AttributeSet attrs) { super(context, attrs); } public LineHistogram(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } public LineHistogram(Context context) { super(context); // TODO Auto-generated constructor stub } @Override protected void onDraw(Canvas canvas) { getWidthHeigth(); getmaxyLength(); Log.v("msg", "hello world data " + String.valueOf(XMAXLENGTH)); Log.v("msg", "heightPixels = " + String.valueOf(heightPixels) + " widthPixels = " + String.valueOf(widthPixels) + " XLength = " + String.valueOf(XLength) + " Ylength = " + String.valueOf(Ylength)); canvas.drawColor(Color.WHITE); paint = new Paint(); paint.setAntiAlias(true); DrawXY(canvas); drawCentreNote(canvas); drawNoteText(canvas); getyaverage(); getAverage(XMAXLENGTH); getxpaverage(); DrawYText(canvas); DrawValuesText(canvas); drawtrue(canvas); drawthink(canvas); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } private void getWidthHeigth() { // DisplayMetrics metrics = getResources().getDisplayMetrics(); // // // 螢幕高 // heightPixels = metrics.heightPixels; // // 螢幕寬 // widthPixels = metrics.widthPixels; // 螢幕高 heightPixels =getHeight(); // 螢幕寬 widthPixels = getWidth(); marginleft=getPaddingLeft()+50f; margintop=getPaddingTop()+60f; // X軸 XLength = widthPixels; // Y軸 Ylength = heightPixels -70; } public void DrawXY(Canvas canvas) { paint.setColor(Color.BLACK); // canvas.drawLine(marginleft, margintop, marginleft + 5, margintop + 5, // paint);// 畫右下箭頭 // canvas.drawLine(marginleft, margintop, marginleft - 5, margintop + 4, // paint);// 畫左上箭頭 canvas.drawLine(marginleft, margintop, marginleft, Ylength, paint); canvas.drawLine(marginleft, Ylength, XLength, Ylength, paint); // canvas.drawLine(XLength - 5.0f, Ylength + 5.0f, XLength, Ylength, paint);// 畫箭頭 // canvas.drawLine(XLength - 5.0f, Ylength - 5.0f, XLength, Ylength, paint);// 畫箭頭 } public void drawNoteText(Canvas canvas) { paint.setColor(Color.BLACK); paint.setTextSize(20); canvas.drawText(NoteText, ((float) ((XLength - paint.measureText(NoteText)) / 2)), margintop+20, paint); } public void drawNote(Canvas canvas) { paint.setColor(truecolor); paint.setTextSize(15); canvas.drawRect(marginleft, Ylength + 45f, marginleft + 10f, Ylength + 55f, paint); canvas.drawText(thinkNoteText, marginleft + 20f, Ylength + 55f, paint); paint.setColor(thinkcolor); canvas.drawLine(marginleft + 30f + paint.measureText(thinkNoteText), Ylength + 40f, marginleft + 43f + paint.measureText(thinkNoteText), Ylength + 50f, paint); canvas.drawText(realityNoteText, marginleft + 50f + paint.measureText(thinkNoteText), Ylength + 55f, paint); canvas.drawLine(0, 492, XLength, 492, paint); } /** * 提示資訊畫中心 * @param canvas */ public void drawCentreNote(Canvas canvas) { float temp=XLength/2;//得到螢幕中間的畫素值 paint.setColor(thinkcolor);//設定顏色 paint.setTextSize(15);//設定字型 //畫圓左邊線 canvas.drawLine(temp-paint.measureText(thinkNoteText)-50f, Ylength+50, temp-paint.measureText(thinkNoteText)-40f, Ylength+50, paint); //畫大圓 canvas.drawCircle(temp-paint.measureText(thinkNoteText)-35f, Ylength+50, 5, paint); //設定顏色 paint.setColor(Color.WHITE); //畫小圓切割大圓成環形 canvas.drawCircle(temp-paint.measureText(thinkNoteText)-35f, Ylength+50, 2.5f, paint); paint.setColor(thinkcolor); //畫圓右邊的線 canvas.drawLine(temp-paint.measureText(thinkNoteText)-30f, Ylength+50, temp-paint.measureText(thinkNoteText)-20f, Ylength+50, paint); paint.setColor(Color.BLACK); //畫提示資訊 canvas.drawText(thinkNoteText, temp-paint.measureText(thinkNoteText)-10, Ylength+55, paint); paint.setColor(truecolor); //畫矩形 canvas.drawRect(temp+10, Ylength+45, temp+20, Ylength+55, paint); paint.setColor(Color.BLACK); //畫提示資訊 canvas.drawText(realityNoteText, temp+30, Ylength+55, paint); canvas.drawText("0", marginleft-10f, Ylength+10, paint); } public String getAverage(double d) { String strRtn = "0"; int intnum = (int) (d / yaverage); int inttemp = Integer .valueOf(getNumber(String.valueOf(intnum).length())); if (inttemp == 1) { strRtn = String .valueOf((int) (d % yaverage) == 0 ? ((int) (d / yaverage)) : ((int) (d / yaverage) + 1)); } else { strRtn = String.valueOf(intnum % inttemp == 0 ? (intnum / inttemp) * inttemp : (intnum / inttemp + 1) * inttemp); } average = Integer.valueOf(strRtn); Log.v("msg", "average = " + String.valueOf(average) + " YMAXLENGTH = " + String.valueOf(YMAXLENGTH)); return strRtn; } public void getyaverage() { yaverage = (int) ((Ylength - margintop - 10) % faverage == 0.0 ? (Ylength - margintop - 10) / faverage : (Ylength - margintop - 10) / faverage); Log.v("msg", "Ylength = " + String.valueOf(Ylength) + " yaverage = " + String.valueOf(yaverage)); Log.v("msg", "data = " + String.valueOf((Ylength - margintop - 10) % faverage) + " length = " + String.valueOf(Ylength - margintop - 10)); Log.v("msg", "rtn1 = " + String.valueOf((Ylength - margintop - 10) / faverage) + " Rtn2 = " + String.valueOf((Ylength - margintop - 10) / faverage)); } public void getxpaverage() { xpaverage = average / faverage; Log.v("msg", "xp =" + String.valueOf(xpaverage)); } public String getNumber(int num) { String strRtn = "1"; if (num > 0) { for (int i = 0; i < num - 1; i++) { strRtn += "0"; } } return strRtn; } public void DrawYText(Canvas canvas) { paint.setColor(Color.BLACK); Float temp = 0.0f; paint.setTextSize(12); for (int i = 1; i < yaverage + 1; i++) { paint.setColor(Color.BLACK); temp = Ylength - Float.valueOf(faverage * i); Log.v("msg", String.valueOf(temp)); // canvas.drawLine(marginleft - 10, temp, marginleft, temp, paint); canvas.drawText(String.valueOf(Integer.valueOf(average) * i), marginleft-paint.measureText(String.valueOf(Integer.valueOf(average) * i))-5, temp + 4.5f, paint); paint.setColor(Color.parseColor("#9EADD1")); canvas.drawLine(marginleft, temp, XLength, temp, paint); } paint.setColor(Color.BLACK); canvas.drawLine(marginleft, margintop, marginleft, margintop+10, paint); paint.setTextSize(15); canvas.drawText(yText,marginleft-paint.measureText(yText)-5f,Ylength-15, paint); canvas.drawText(xText,marginleft,Ylength+40, paint); } public void DrawValuesText(Canvas canvas) { paint.setColor(Color.BLACK); float temp = marginleft-20f; for (int i = 0; i < ValuesText.length; i++) { temp += yspace; canvas.drawLine(temp, Ylength, temp, Ylength + 5f, paint); canvas.drawText(ValuesText[i], temp - (paint.measureText(ValuesText[i])/2), Ylength + 20f, paint); } } public void getmaxyLength() { double temp = thinkValues[0]; for (int i = 1; i < thinkValues.length; i++) { if (temp < thinkValues[i]) { temp = thinkValues[i]; } } for (int i = 0; i <realityValues.length; i++) { if (temp < realityValues[i]) { temp = realityValues[i]; } } XMAXLENGTH = (float) temp; } public void DrawXthinkText(Canvas canvas) { float temp = marginleft-20; for (int i = 0; i < thinkValues.length; i++) { temp += yspace; paint.setColor(thinkcolor); canvas.drawRect(temp - 20.0f, Ylength - (float) (thinkValues[i]), temp, Ylength, paint); canvas.drawText(String.valueOf((int) thinkValues[i]), temp - 20.0f, (float) (Ylength - thinkValues[i] - 3.0f), paint); paint.setColor(truecolor); canvas.drawRect(temp, Ylength - (float) (realityValues[i]), temp + 20.f, Ylength, paint); canvas.drawText(String.valueOf((int) realityValues[i]), temp, (float) (Ylength - realityValues[i] - 3.0f), paint); Log.v("msg", "data" + String.valueOf(Ylength - (float) (thinkValues[i]))); } } public void drawthink(Canvas canvas) { paint.setColor(thinkcolor); float temp = marginleft-20; for (int i = 0; i < thinkValues.length - 1; i++) { temp += yspace; canvas.drawLine(temp, Ylength - (float) (thinkValues[i] / xpaverage), temp += yspace, Ylength - (float) (thinkValues[i + 1] / xpaverage), paint); temp -= yspace; } temp = marginleft-20; for (int i = 0; i < thinkValues.length; i++) { temp += yspace; paint.setColor(thinkcolor); canvas.drawText(String.valueOf(thinkValues[i]), temp - (paint.measureText(String.valueOf(thinkValues[i]))/2), Ylength - (float) (thinkValues[i] / xpaverage) - 7.0f, paint); canvas.drawCircle(temp, Ylength - (float) (thinkValues[i] / xpaverage), 5.0f, paint); paint.setColor(Color.WHITE); canvas.drawCircle(temp, Ylength - (float) (thinkValues[i] / xpaverage), 2.5f, paint); } } public void drawtrue(Canvas canvas) { float temp = marginleft-20; paint.setColor(truecolor); for (int i = 0; i < realityValues.length; i++) { temp += yspace; canvas.drawRect(temp - 15.0f, Ylength - (float) (realityValues[i] / xpaverage), temp + 15.0f, Ylength, paint); } paint.setColor(Color.BLACK); temp = marginleft-20; for (int i = 0; i < realityValues.length; i++) { temp += yspace; canvas.drawText(String.valueOf(realityValues[i]), temp - (paint.measureText(String.valueOf(realityValues[i]))/2), Ylength - 20.0f, paint); } } private int measureWidth(int measureSpec) { paint=new Paint(); int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be result = specSize; } else { // Measure the text if(mText.equals("")){ DisplayMetrics metrics = getResources().getDisplayMetrics(); result = (int) (metrics.widthPixels<getAcquiesceWhidth()?getAcquiesceWhidth():metrics.widthPixels+getPaddingLeft() + getPaddingRight()); }else{ result = (int) paint.measureText(mText) + getPaddingLeft() + getPaddingRight(); } if (specMode == MeasureSpec.AT_MOST) { // Respect AT_MOST value if that was what is called for by // measureSpec result = Math.min(result, specSize); } } return result; } /** * Determines the height of this view * * @param measureSpec * A measureSpec packed into an int * @return The height of the view, honoring constraints from measureSpec */ private int measureHeight(int measureSpec) { paint = new Paint(); int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); mAscent = (int) paint.ascent(); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be result = specSize; } else { if (mText.equals("")) { DisplayMetrics metrics = getResources().getDisplayMetrics(); result = (int) (metrics.heightPixels-150 + getPaddingLeft() + getPaddingRight()); } else { result = (int) (-mAscent + paint.descent()) + getPaddingTop() + getPaddingBottom(); } if (specMode == MeasureSpec.AT_MOST) { result = Math.min(result, specSize); } } return result; } public float getAcquiesceWhidth(){ float rtn=100; if(ValuesText.length>0){ rtn=getPaddingLeft()+40+(yspace*(ValuesText.length+1)); } return rtn; } public String getNoteText() { return NoteText; } public void setNoteText(String noteText) { NoteText = noteText; } public String getThinkNoteText() { return thinkNoteText; } public void setThinkNoteText(String thinkNoteText) { this.thinkNoteText = thinkNoteText; } public String getRealityNoteText() { return realityNoteText; } public void setRealityNoteText(String realityNoteText) { this.realityNoteText = realityNoteText; } public String[] getValuesText() { return ValuesText; } public void setValuesText(String[] valuesText) { ValuesText = valuesText; } public double[] getThinkValues() { return thinkValues; } public void setThinkValues(double[] thinkValues) { this.thinkValues = thinkValues; } public double[] getRealityValues() { return realityValues; } public void setRealityValues(double[] realityValues) { this.realityValues = realityValues; } @Override public String toString() { return "LineHistogram [mAscent=" + mAscent + ", mText=" + mText + ", NoteText=" + NoteText + ", thinkNoteText=" + thinkNoteText + ", realityNoteText=" + realityNoteText + ", ValuesText=" + Arrays.toString(ValuesText) + ", thinkValues=" + Arrays.toString(thinkValues) + ", realityValues=" + Arrays.toString(realityValues) + "]"; } }
用法
/**大類數量比例**/
private Cookie mCkAddTypeQuantity;
/**預期和實際對比**/
private LineHistogram mHgAddContrast;
public void getDataContrast(String muserID) { SqlStatistics service = new SqlStatistics(getActivity()); DHHApp.setUserId("J0049"); ArrayList<OrderStatistics> arrayList = service.getSumAmount(true); Logs.v("msg", "test data = " + arrayList.toString()); String[] thinkdata = new String[arrayList.size()]; double[] thinkNumber = new double[arrayList.size()]; double[] trueNumber = new double[arrayList.size()]; int intcount = 0; for (OrderStatistics orderStatistics : arrayList) { thinkdata[intcount] = orderStatistics.getShowName(); thinkNumber[intcount] = orderStatistics.getShowSecondNumber(); trueNumber[intcount]=orderStatistics.getShowNumber(); intcount++; } mHgAddContrast.setValuesText(thinkdata); mHgAddContrast.setThinkValues(thinkNumber); mHgAddContrast.setRealityValues(trueNumber); mHgAddContrast.setRealityNoteText("實際訂購金額"); mHgAddContrast.setThinkNoteText("計劃訂購金額"); mHgAddContrast.setNoteText(""); }
佈局
<RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <com.wforyou.dhh.ui.widget.LineHistogram android:id="@+id/user_LineHistogram_Contrast" android:layout_width="match_parent" android:layout_height="fill_parent" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="35dp" android:layout_marginTop="20dp" android:background="@drawable/bg_tb_left" android:paddingLeft="60dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginTop="20dp" android:background="@drawable/bg_user_plancontrast" /> </RelativeLayout>