由于最新项目需要用到图表显示数据,所以参考网上的资源,写了一个demo,主要是通过在Activity发送不同的数据到view里面刷新显示,每发送一次数据,就显示几个随机数到view显示。
显示效果如图:
这里写图片描述
代码注释比较详细,就不做太多说明了。
ZywChartView.java
@SuppressLint("DrawAllocation")
public class ZywChartView extends View {
private String TAG = "ZywChartView";
// 默认边距
private float Margin = 40;
//圆半径
private int circleRadius = 8;
// X,Y轴的单位长度
private float Xscale = 20;
private float Yscale = 20;
//X轴第1个节点到最后1个节点的长度
private float xLength;
//Y轴第1个节点到最后1个节点的长度
private float yLength;
//X轴第1个节点的偏移量
private float xFirstPointOffset;
//y轴显示的节点间隔距离
private int yScaleForData = 5;
//画线颜色
private int lineColor = this.getResources().getColor(R.color.saswell_yellow);
// 原点坐标
private float Xpoint;
private float Ypoint;
private String yUnit = "";
private String xUnit = "";
// X,Y轴上面的显示文字
private String[] Xlabel = { "1", "2", "3", "4", "5", "6", "7"};
private String[] Ylabel = { "0", "1", "2", "3", "4", "5", "6", "7", "8",
"9", "10" };
private final static int Y_SCALE_FOR_DATA_DAY = 5;
private final static int Y_SCALE_FOR_DATA_WEEK = 2;
private final static int Y_SCALE_FOR_DATA_MOUNTH = 2;
// 曲线数据
private int[] Data = {5, 5, 5, 5, 5, 5, 5};
public ZywChartView(Context context, String[] xlabel, String[] ylabel, int[] data) {
super(context);
this.Xlabel = xlabel;
this.Ylabel = ylabel;
this.Data = data;
}
public ZywChartView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Log.e(TAG,"ZywChartView(Context context, AttributeSet attrs, int defStyleAttr)");
}
public ZywChartView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
xFirstPointOffset = 2 * this.Margin;
Log.e(TAG,"ZywChartView(Context context, AttributeSet attrs)");
}
public ZywChartView(Context context) {
super(context);
Log.e(TAG,"ZywChartView(Context context)");
}
/**
* 设置显示的数据
* @param str要显示的数据字符串
* @author zyw
*/
public void setData(String str){
String[] tempData;
tempData = str.split(",");
int yDataLength = 0;
Log.e(TAG, "str = " + str);
Data = new int[tempData.length];
Xlabel = new String[tempData.length];
if(tempData.length >= 28){
yScaleForData = Y_SCALE_FOR_DATA_MOUNTH;
yDataLength = 25;
xUnit = getResources().getString(R.string.x_unit_month);
yUnit = getResources().getString(R.string.y_unit_month);
}else if(tempData.length >= 12){
yScaleForData = Y_SCALE_FOR_DATA_DAY;
yDataLength = 61;
xUnit = getResources().getString(R.string.x_unit_day);
yUnit = getResources().getString(R.string.y_unit_day);
}else{
yScaleForData = Y_SCALE_FOR_DATA_WEEK;
yDataLength = 25;
xUnit = getResources().getString(R.string.x_unit_week);
yUnit = getResources().getString(R.string.y_unit_week);
}
Ylabel = new String[yDataLength];
for(int i = 0; i < yDataLength; i++){
Ylabel[i] = Integer.toString(i);
//Log.e(TAG,"Ylable[" + i + "]" + Ylabel[i]);
}
for(int i = 0; i < tempData.length; i++){
Data[i] = Integer.parseInt(tempData[i]);
//Log.e(TAG,"Data[" + i + "]" + Data[i]);
Xlabel[i] = Integer.toString(i + 1);
Log.e(TAG,"Xlable[" + i + "]" + Xlabel[i]);
}
invalidate();
}
// 初始化数据
public void init() {
Xpoint = this.Margin;
Log.e(TAG, "this.getHeight() == " + this.getHeight());
Ypoint = this.getHeight() - this.Margin;
Xscale = (this.getWidth() - 4 * this.Margin) / (this.Xlabel.length);
Yscale = (this.getHeight() - 3 * this.Margin) / (this.Ylabel.length);
xLength = this.getWidth() - (4 * this.Margin);
yLength = this.getHeight() - (2 * this.Margin);
xFirstPointOffset = Xscale;
}
public float getMargin() {
return Margin;
}
public void setMargin(int margin) {
Margin = margin;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
Log.e(TAG, "onDraw");
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setColor(lineColor);
paint.setStrokeWidth(3);
init();
this.drawXLine(canvas, paint);
this.drawYLine(canvas, paint);
this.drawDashPath(canvas);
this.drawData(canvas);
this.drawXUnit(canvas);
this.drawYUnit(canvas);
}
//画虚线
private void drawDashPath(Canvas canvas) {
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(lineColor);
paint.setStrokeWidth(3);
Path path = new Path();
//绘制长度为10的实线,再绘制长度为10的空白,再绘制长度为10的实线,再回执长度为10的空白,依次重复,1为偏移量
PathEffect effects = new DashPathEffect(new float[] { 10, 10, 10, 10}, 1);
paint.setPathEffect(effects);
// 纵向线
for (int i = 0; i * Xscale < xLength; i++) {
float startX = Xpoint + i * Xscale + xFirstPointOffset;
float startY = Ypoint;
float stopY = calY(Data[i]);
path.moveTo(startX, startY);
path.lineTo(startX, stopY);
canvas.drawPath(path, paint);
}
}
private void drawXUnit(Canvas canvas) {
Paint p = new Paint();
p.setAntiAlias(true);
p.setColor(lineColor);
p.setStrokeWidth(2);
p.setTextSize(this.Margin / 2);
canvas.drawText(xUnit, this.getWidth() - this.Margin * 2 + this.Margin / 4, Ypoint + this.Margin / 5, p);
}
private void drawYUnit(Canvas canvas) {
Paint p = new Paint();
p.setAntiAlias(true);
p.setColor(lineColor);
p.setStrokeWidth(2);
p.setTextSize(this.Margin / 2);
canvas.drawText(yUnit, this.Margin / 2, this.Margin / 2, p);
}
// 画横纵轴
private void drawXLine(Canvas canvas, Paint p) {
canvas.drawLine(Xpoint, Ypoint, this.getWidth() - this.Margin * 2, Ypoint,
p);
canvas.drawLine(this.getWidth() - this.Margin * 2, Ypoint, this.getWidth()
- this.Margin * 2 - this.Margin / 3, Ypoint - this.Margin / 3, p);
canvas.drawLine(this.getWidth() - this.Margin * 2, Ypoint, this.getWidth()
- this.Margin * 2 - this.Margin / 3, Ypoint + this.Margin / 3, p);
}
private void drawYLine(Canvas canvas, Paint p) {
canvas.drawLine(Xpoint, Ypoint, this.Margin, this.Margin, p);
canvas.drawLine(Xpoint, this.Margin, Xpoint - Xpoint / 3, this.Margin
+ this.Margin / 3, p);
canvas.drawLine(Xpoint, this.Margin, Xpoint + Xpoint / 3, this.Margin
+ this.Margin / 3, p);
}
// 画数据
private void drawData(Canvas canvas) {
Paint p = new Paint();
p.setAntiAlias(true);
p.setColor(lineColor);
p.setStrokeWidth(3);
p.setTextSize(this.Margin / 2);
//横向
for (int i = 0; i * Xscale < xLength; i++) {
float startX = Xpoint + i * Xscale + xFirstPointOffset;
canvas.drawText(this.Xlabel[i], startX - this.Margin / 4,
this.getHeight() - this.Margin / 4, p);
canvas.drawCircle(startX, calY(Data[i]), circleRadius, p);
if(i != 0){
canvas.drawLine(Xpoint + (i - 1) * Xscale + xFirstPointOffset, calY(Data[i-1]), startX, calY(Data[i]), p);
}
}
//纵向
for (int i = 0; (yLength - i * Yscale) >= this.Margin; i += yScaleForData) {
float startY = Ypoint - i * Yscale;
canvas.drawText(this.Ylabel[i], this.Margin / 4, startY
+ this.Margin / 4, p);
}
}
/**
*
* @param y
* @return
*/
private float calY(int y){
int y0 = 0 ;
int y1 = 0 ;
// Log.i("zzzz", "y:"+y);
try{
y0 = Integer.parseInt(Ylabel[0]);
// Log.i("zzzz", "y0"+y0);
y1 = Integer.parseInt(Ylabel[1]);
// Log.i("zzzz","y1"+y1);
}catch(Exception e){
// Log.i("zzzz", "string changed is err");
return 0;
}
try{
// Log.i("zzzz", "返回数据"+(Ypoint-(y-y0)*Yscale/(y1-y0)) );
return Ypoint - ((y-y0) * Yscale/(y1-y0));
}catch(Exception e){
// Log.i("zzzz", "return is err");
return 0;
}
}
}
EnergyConsumptionActivity.java
public class EnergyConsumptionActivity extends Activity{
private int randomNum;
private RadioGroup rgModeSelect;
private RadioButton rbDayMode,rbWeekMode,rbMonthMode;
private String TAG = "MainActivity";
private Button btnSetData,btnTitle;
private ZywChartView myView;
private String strData;
private int mode,randomDataLength = 10;
private final static int DAY_MODE = 1;
private final static int WEEK_MODE = 2;
private final static int MONTH_MODE = 3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_energy_consumption);
init();
}
private OnClickListener onClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnSetData:
Log.e("ZYW", "set Data.");
sendData(mode);
break;
case R.id.title_back:
Log.e(TAG,"finish.");
finish();
break;
default:
break;
}
}
};
private OnCheckedChangeListener checkedChangeListener = new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
try {
switch(checkedId){
case R.id.rbDayMode:
mode = DAY_MODE;
randomDataLength = 60;
break;
case R.id.rbWeekMode:
mode = WEEK_MODE;
randomDataLength = 24;
break;
case R.id.rbmonthMode:
mode = MONTH_MODE;
randomDataLength = 24;
break;
}
sendData(mode);
Log.e(TAG, "mode = " + mode);
} catch (Exception e) {
e.printStackTrace();
}
}
};
/**
* 在0-randomDataLength中生成一个随机数
* @return 随机生成的数字组合字符串: data1,data2,data3,...dataN
*/
public String getRandomNum(int mode){
String strRandomNum = "";
int maxI = 7;
//根据模式(天、周、月)确定要绘制的折线图
switch (mode) {
case DAY_MODE:
maxI = 12;
break;
case WEEK_MODE:
maxI = 7;
break;
case MONTH_MODE:
maxI = 30;
break;
default:
Log.e(TAG, "mode is error");
break;
}
for(int i = 0; i < maxI; i++){
//在0-randomDataLength中生成一个随机数
randomNum = (int) (Math.random()*randomDataLength);
//Log.e(TAG, "randomNum ==" + randomNum);
if(i != (maxI - 1)){
strRandomNum += randomNum + ",";
}
else{
strRandomNum += randomNum;
}
}
Log.e(TAG, "strRandomNum ==" + strRandomNum);
return strRandomNum;
}
/**
* 发送数据
* @param mode
*/
public void sendData(int mode){
strData = getRandomNum(mode);
myView.setData(strData);
}
public void init(){
btnSetData = (Button) findViewById(R.id.btnSetData);
btnTitle = (Button) findViewById(R.id.title_back);
myView = (ZywChartView) findViewById(R.id.myView);
rbDayMode = (RadioButton) findViewById(R.id.rbDayMode);
rbWeekMode = (RadioButton) findViewById(R.id.rbWeekMode);
rbMonthMode = (RadioButton) findViewById(R.id.rbmonthMode);
rgModeSelect = (RadioGroup) findViewById(R.id.rgModeSelect);
rgModeSelect.setOnCheckedChangeListener(checkedChangeListener);
btnTitle.setOnClickListener(onClickListener);
btnSetData.setOnClickListener(onClickListener);
rbDayMode.setChecked(true);
}
}
网友评论