实现简单的柱状图
package com.machenglin.rectview;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import com.machenglin.slidingapp.R;
public class HistogramView extends View {
private Paint mTextPaint = null;
private Paint mLinePaint = null;
private Paint mAxisPaint = null;
private Paint mHistogramPaint = null;
private String[] mXAxis = null;
private String[] mYAxis = null;
private float[] mHistogram = null;
private Rect mChartRect = null;
private int mHistogramWidth = 50;
private int mHistogramColor = Color.GREEN;
private int mTextColor = Color.BLACK;
private int mLineColor = Color.GRAY;
private int mTextSize = 30;
private int mLineMarginLeft = 0;
private int mLineMarginBottom = 0;
public HistogramView(Context context) {
this(context, null);
}
public HistogramView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public HistogramView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.HistogramView);
if (ta != null) {
mHistogramWidth = ta.getDimensionPixelOffset(R.styleable.HistogramView_histogramWidth, 50);
//mTextPaintColor = ta.getColor(R.styleable.HistogramView_textColor, Color.BLACK);
mLineColor = ta.getColor(R.styleable.HistogramView_lineColor, Color.GRAY);
mTextSize = ta.getDimensionPixelOffset(R.styleable.HistogramView_textSize, 30);
mHistogramColor = ta.getColor(R.styleable.HistogramView_rectColor, Color.GREEN);
mLineMarginLeft = ta.getDimensionPixelOffset(R.styleable.HistogramView_lineMarginLeft, 0);
mLineMarginBottom = ta.getDimensionPixelOffset(R.styleable.HistogramView_lineMarginBottom, 0);
ta.recycle();
}
init();
}
private void init() {
mTextPaint = new Paint();
mAxisPaint = new Paint();
mLinePaint = new Paint();
mHistogramPaint = new Paint();
mTextPaint.setColor(mTextColor);
mLinePaint.setColor(mLineColor);
mTextPaint.setTextSize(mTextSize);
mHistogramPaint.setColor(mHistogramColor);
mHistogramPaint.setStyle(Paint.Style.FILL);
mTextPaint.setAntiAlias(true);
mHistogramPaint.setAntiAlias(true);
mLinePaint.setAntiAlias(true);
mChartRect = new Rect();
setAixs(new String[]{"周一", "周二", "周三"}, new String[]{"10", "5", "0"});
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
getDrawingRect(mChartRect);
drawText(canvas);
drawAxis(canvas);
drawRect(canvas);
}
private void drawRect(Canvas canvas) {
int width = mChartRect.right - mChartRect.left;
int height = mChartRect.bottom - mChartRect.top;
if (mXAxis != null) {
int xLength = mXAxis.length;
int ave = (int) (width - calculateTextWidth(mTextPaint, mXAxis[(xLength - 1) >= 0 ? (xLength - 1) : 0])) / (xLength - 1);
for (int i = 0; i < xLength; i++) {
//canvas.drawText(mXAxis[i], mChartRect.left + (ave * i), mChartRect.bottom, mTextPaint);
float centerX = mChartRect.left + (ave * i) + mTextPaint.measureText(mXAxis[i]) / 2;
Rect rect = new Rect();
rect.top = (int) ((float)(10 - mHistogram[i]) / 10 * height);
rect.left = (int) (centerX - mHistogramWidth / 2);
rect.bottom = mChartRect.bottom;
rect.right = (int) (centerX + mHistogramWidth / 2);
canvas.drawRect(rect, mHistogramPaint);
}
}
}
/**
* 画坐标轴
* @param canvas
*/
private void drawAxis(Canvas canvas) {
//canvas.drawLine(mChartRect.left, mChartRect.top, mChartRect.left, mChartRect.bottom, mLinePaint);
canvas.drawLine(mChartRect.left, mChartRect.bottom, mChartRect.right, mChartRect.bottom, mAxisPaint);
}
/**
* 画横纵坐标
* @param canvas
*/
private void drawText(Canvas canvas) {
int textHeight = (int) calculateTextHeight(mTextPaint);
// 画x轴坐标
int maxWidth = getMaxTextWidth();
int width = mChartRect.right - mChartRect.left - maxWidth - mLineMarginLeft;
if (mXAxis != null) {
int xLength = mXAxis.length;
int ave = 0;
if (xLength > 1) {
ave = (int) (width - calculateTextWidth(mTextPaint, mXAxis[(xLength - 1) >= 0 ? (xLength - 1) : 0])) / (xLength - 1);
}
for (int i = 0; i < xLength; i++) {
canvas.drawText(mXAxis[i], mChartRect.left + maxWidth + mLineMarginLeft + (ave * i), mChartRect.bottom - mTextPaint.getFontMetrics().descent, mTextPaint);
}
}
mChartRect.bottom = (int) (mChartRect.bottom - calculateTextHeight(mTextPaint) - mLineMarginBottom);
// 画y轴坐标
int height = mChartRect.bottom - mChartRect.top;
if (mYAxis != null) {
int yLength = mYAxis.length;
int ave = 0;
if (yLength > 1) {
ave = (height - textHeight) / (yLength - 1);
}
for (int i = 0; i < yLength; i++) {
canvas.drawText(mYAxis[i], mChartRect.left, textHeight + i * ave, mTextPaint);
}
mChartRect.left = mChartRect.left + maxWidth + mLineMarginLeft;
int centerY = textHeight * 2 / 3;
for (int i = 0; i < (yLength - 1); i++) {
canvas.drawLine(mChartRect.left, centerY + i * ave, mChartRect.right, centerY + i * ave, mLinePaint);
}
}
}
private float calculateTextHeight(Paint paint) {
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
return (fontMetrics.descent - fontMetrics.ascent);
}
private float calculateTextWidth(Paint paint, String str) {
return paint.measureText(str);
}
private void setAixs(String[] xAixs, String[] yAxis) {
this.mXAxis = xAixs;
this.mYAxis = yAxis;
mHistogram = new float[]{1, 2, 6};
this.postInvalidate();
}
public int getMaxTextWidth() {
if (mYAxis == null || mYAxis.length == 0) return 0;
float max = 0;
for (String str : mYAxis) {
float value = calculateTextWidth(mTextPaint, str);
if (max < value) {
max = value;
}
}
return (int) Math.ceil(max);
}
}