功能:叠加显示两组数据,需要先将纵坐标值换算成到顶部的距离值,因此先计算出k和b。另外maxY和minY的更新可以让图表自适应数据的变化。
public class SimpleBarChartView extends View {
private int maxY = 0;
private int minY = 0;
private double k = 0;
private double b = 0;
private int chartHeight = 500;
private int blackHeight = 20;
private int[] foregroudTraffic;
private int[] backgroundTraffic;
private int[] yLabels =
new int[]{80000, 60000, 40000, 20000, 0};
private String[] xTitles =
new String[]{"1", "2", "3", "4", "5", "6", "7"};
public SimpleBarChartView(Context context, int[] foregroudTraffic, int[] backgroundTraffic, String[] xTitles) {
super(context);
init(context, null);
this.foregroudTraffic = foregroudTraffic;
this.backgroundTraffic = backgroundTraffic;
this.xTitles = xTitles;
updateKandB();
updateYLabels();
this.postInvalidate(); //可以子线程 更新视图的方法调用。
}
public SimpleBarChartView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
// 坐标轴 轴线 画笔:
private Paint axisLinePaint;
// 坐标轴水平内部 虚线画笔
private Paint hLinePaint;
// 绘制文本的画笔
private Paint titlePaint;
// 矩形画笔 柱状图的样式信息
private Paint recPaint;
private void init(Context context, AttributeSet attrs) {
axisLinePaint = new Paint();
hLinePaint = new Paint();
titlePaint = new Paint();
recPaint = new Paint();
axisLinePaint.setColor(Color.DKGRAY);
hLinePaint.setColor(Color.LTGRAY);
titlePaint.setColor(Color.BLACK);
}
private void updateMinYAndMaxY() {
if (foregroudTraffic != null && foregroudTraffic.length > 0) {
int thisCount = foregroudTraffic.length;
for (int i = 0; i < thisCount; i++) {
minY = foregroudTraffic[i]+backgroundTraffic[i] < minY ? foregroudTraffic[i]+backgroundTraffic[i] : minY;
maxY = foregroudTraffic[i]+backgroundTraffic[i] > maxY ? foregroudTraffic[i]+backgroundTraffic[i] : maxY;
}
}
}
private void updateYLabels() {
for (int i = 0; i < yLabels.length; i++) {
yLabels[i] = (yLabels.length - 1 - i) * (maxY) / (yLabels.length - 1);
}
}
private void updateKandB() {
updateMinYAndMaxY();
k = (chartHeight - blackHeight) / (double) (minY - maxY);
b = blackHeight - k * maxY;
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
canvas.drawLine(100, 10, 100, chartHeight, axisLinePaint);
canvas.drawLine(100, chartHeight, width - 10, chartHeight, axisLinePaint);
int leftHeight = chartHeight - 20;// 左侧外周的 需要划分的高度:
int hPerHeight = leftHeight / 4;
hLinePaint.setTextAlign(Align.CENTER);
for (int i = 0; i < 4; i++) {
canvas.drawLine(100, 20 + i * hPerHeight, width - 10, 20 + i * hPerHeight, hLinePaint);
}
FontMetrics metrics = titlePaint.getFontMetrics();
int descent = (int) metrics.descent;
titlePaint.setTextAlign(Align.RIGHT);
for (int i = 0; i < yLabels.length; i++) {
canvas.drawText("" + yLabels[i], chartHeight / 4, 20 + i * hPerHeight + descent, titlePaint);
}
int xAxisLength = width - 110;
int columCount = xTitles.length + 1;
int step = xAxisLength / columCount;
for (int i = 0; i < columCount - 1; i++) {
canvas.drawText(xTitles[i], 100 + step * (i + 1), chartHeight + 20, titlePaint);
}
if (foregroudTraffic != null && foregroudTraffic.length > 0) {
int thisCount = foregroudTraffic.length;
for (int i = 0; i < thisCount; i++) {
int value = foregroudTraffic[i]+backgroundTraffic[i];
int topValue = (int) (k * value + b);
recPaint.setColor(0xFF1078CF);
Rect rect = new Rect();
rect.left = 100 + step * (i + 1) - 10;
rect.right = 100 + step * (i + 1) + 10;
rect.top = topValue;
rect.bottom = chartHeight;
canvas.drawRect(rect, recPaint);
}
}
if (backgroundTraffic != null && backgroundTraffic.length > 0) {
int thisCount = backgroundTraffic.length;
for (int i = 0; i < thisCount; i++) {
int value = backgroundTraffic[i];
int topValue = (int) (k * value + b);
recPaint.setColor(0xFFAA1122);
Rect rect = new Rect();
rect.left = 100 + step * (i + 1) - 10;
rect.right = 100 + step * (i + 1) + 10;
rect.top = topValue;
rect.bottom = chartHeight;
canvas.drawRect(rect, recPaint);
}
}
}
}