LineChartView—自定义折线统计图
<declare-styleable name="LineChartView">
<attr name="line_title_text" format="string" />
<attr name="line_start_point_x" format="integer" />
<attr name="line_start_point_y" format="integer" />
<attr name="line_delta_x" format="integer" />
<attr name="line_delta_y" format="integer" />
<attr name="line_conut_x" format="integer" />
<attr name="line_conut_y" format="integer" />
<attr name="line_padding_left" format="dimension" />
<attr name="line_padding_right" format="dimension" />
<attr name="line_text_size" format="dimension" />
</declare-styleable>
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/**
* Created by hdz on 2017/1/12.
*/
public class LineChartView extends View {
private String titleText="鍚堝悓璁″垝";
private int startPointX;
private int startPointY;
private int deltaX; //the delta between two x_value
private int deltaY;
private int countX; //the count of the x (for example a week is seven and a year is twelve)
private int countY;
private float paddingLeft;
private float paddingRight;
private float textSize;
private Paint paint;
private Paint linePaint;
private TextPaint textPaint;
private Path path;
private List<Integer> dataList;
public LineChartView(Context context) {
this(context, null);
}
public LineChartView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LineChartView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(context, attrs, defStyleAttr);
init();
}
private void initAttrs(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.LineChartView, defStyleAttr, 0);
titleText = array.getString(R.styleable.LineChartView_line_title_text);
startPointX = array.getInteger(R.styleable.LineChartView_line_start_point_x, 0);
startPointY = array.getInteger(R.styleable.LineChartView_line_start_point_y, 0);
deltaX = array.getInteger(R.styleable.LineChartView_line_delta_x, 0);
deltaY = array.getInteger(R.styleable.LineChartView_line_delta_y, 0);
countX = array.getInteger(R.styleable.LineChartView_line_conut_x, 0);
countY = array.getInteger(R.styleable.LineChartView_line_conut_y, 0);
// paddingLeft = array.getDimensionPixelSize(R.styleable.LineChartView_line_padding_left, 0);
// paddingRight = array.getDimensionPixelSize(R.styleable.LineChartView_line_padding_right, 0);
textSize = array.getDimensionPixelSize(R.styleable.LineChartView_line_text_size, 0);
array.recycle();
}
private void init() {
paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(5);
textPaint = new TextPaint();
textPaint.setAntiAlias(true);
path = new Path();
linePaint = new Paint();
linePaint.setColor(0xff2665ac);
linePaint.setAntiAlias(true);
linePaint.setStyle(Paint.Style.STROKE);
linePaint.setStrokeWidth(5);
dataList = new ArrayList<Integer>();
dataList.add(56);
dataList.add(76);
dataList.add(89);
dataList.add(36);
dataList.add(90);
dataList.add(19);
dataList.add(80);
dataList.add(80);
}
private void setList(List<Integer> dataList) {
this.dataList = dataList;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//get the padding
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
int paddingBottom = getPaddingBottom();
int paddingTop = getPaddingTop();
int height = getHeight();
int width = getWidth();
textPaint.setColor(0xff2665ac);
textPaint.setTextSize(textSize);
canvas.drawText(titleText, 0.5f * width - textPaint.measureText(titleText) * 0.5f, paddingTop + textPaint.getFontMetrics().bottom * 4, textPaint);
//琛ㄦ牸鐨勮捣濮嬬偣
float startY = (textPaint.getFontMetrics().bottom * 4) * 2 + paddingTop;
float startX = textSize * 2 + paddingLeft;
float endY = height - textSize * 3 - paddingBottom;
float endX = width - (textSize + paddingRight);
//textSize * 2 杩欐绌洪棿鏄敤鏉ュ啓妯潗鏍囩殑
//height - startY - textSize * 3 - paddingBottom 鐢ㄤ簬鐢诲浘鐨勯珮搴?
float chartHeight = endY - startY;
float chartWidth = endX - startX;
float deltaDistanceY = chartHeight / countY;
float deltaDistanceX = chartWidth / countX;
//鐢绘í绾?
for (int i = 0; i <= countY; i++) {
if (i == countY) {
paint.setColor(0xff000000);
} else {
paint.setColor(0xffdddddd);
}
String numberY = ((countY - i) * deltaY) + "";
canvas.drawText(numberY, startX - (0.5f * textSize + textPaint.measureText(numberY)), startY + deltaDistanceY * i + textPaint.getFontMetrics().bottom * 2, textPaint);
canvas.drawLine(startX, startY + i * deltaDistanceY, endX, startY + i * deltaDistanceY, paint);
}
//鐢荤珫绾?
for (int i = 0; i <= countX; i++) {
if (i == 0) {
paint.setColor(0xff000000);
} else {
paint.setColor(0xffdddddd);
}
String numberX = "" + (startPointX + i * deltaX);
canvas.drawLine(startX + i * deltaDistanceX, startY, startX + i * deltaDistanceX, endY, paint);
canvas.drawText(numberX, startX + i * deltaDistanceX - textPaint.measureText(numberX) * 0.5f, endY + textPaint.getFontMetrics().bottom * 4 + 5, textPaint);
}
//鐢绘姌绾?
path.moveTo(startX, endY - dataList.get(0) * 1.0f / deltaY * deltaDistanceY);
for (int i = 0; i < dataList.size(); i++) {
float cx = startX + i * deltaDistanceX;
float cy = endY - dataList.get(i) * 1.0f / deltaY * deltaDistanceY;
canvas.drawText(dataList.get(i) + "", cx - textPaint.measureText(dataList.get(i) + "") * 0.5f, cy - textPaint.getFontMetrics().bottom * 3, textPaint);
paint.setColor(Color.RED);
canvas.drawCircle(cx, cy, 15, paint);
paint.setColor(Color.WHITE);
canvas.drawCircle(cx, cy, 10, paint);
paint.setColor(Color.RED);
canvas.drawCircle(cx, cy, 5, paint);
if (i == 0) {
} else {
path.lineTo(cx, cy);
}
}
canvas.drawPath(path, linePaint);
}
}
<com.hdz.widget.LineChartView
android:layout_width="match_parent"
android:padding="10dp"
app:line_conut_x="7"
app:line_conut_y="5"
app:line_delta_x="1"
app:line_delta_y="20"
app:line_start_point_x="3"
app:line_text_size="20sp"
app:line_title_text="项目成本" />