由于最新項(xiàng)目需要用到圖表顯示數(shù)據(jù),所以參考網(wǎng)上的資源,寫(xiě)了一個(gè)demo二鳄,主要是通過(guò)在Activity發(fā)送不同的數(shù)據(jù)到view里面刷新顯示,每發(fā)送一次數(shù)據(jù)媒怯,就顯示幾個(gè)隨機(jī)數(shù)到view顯示订讼。
顯示效果如圖:
代碼注釋比較詳細(xì),就不做太多說(shuō)明了扇苞。
ZywChartView.java
@SuppressLint("DrawAllocation")
public class ZywChartView extends View {
private String TAG = "ZywChartView";
// 默認(rèn)邊距
private float Margin = 40;
//圓半徑
private int circleRadius = 8;
// X,Y軸的單位長(zhǎng)度
private float Xscale = 20;
private float Yscale = 20;
//X軸第1個(gè)節(jié)點(diǎn)到最后1個(gè)節(jié)點(diǎn)的長(zhǎng)度
private float xLength;
//Y軸第1個(gè)節(jié)點(diǎn)到最后1個(gè)節(jié)點(diǎn)的長(zhǎng)度
private float yLength;
//X軸第1個(gè)節(jié)點(diǎn)的偏移量
private float xFirstPointOffset;
//y軸顯示的節(jié)點(diǎn)間隔距離
private int yScaleForData = 5;
//畫(huà)線顏色
private int lineColor = this.getResources().getColor(R.color.saswell_yellow);
// 原點(diǎn)坐標(biāo)
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;
// 曲線數(shù)據(jù)
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)");
}
/**
* 設(shè)置顯示的數(shù)據(jù)
* @param str要顯示的數(shù)據(jù)字符串
* @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();
}
// 初始化數(shù)據(jù)
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);
}
//畫(huà)虛線
private void drawDashPath(Canvas canvas) {
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(lineColor);
paint.setStrokeWidth(3);
Path path = new Path();
//繪制長(zhǎng)度為10的實(shí)線欺殿,再繪制長(zhǎng)度為10的空白,再繪制長(zhǎng)度為10的實(shí)線鳖敷,再回執(zhí)長(zhǎng)度為10的空白脖苏,依次重復(fù),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);
}
// 畫(huà)橫縱軸
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);
}
// 畫(huà)數(shù)據(jù)
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", "返回?cái)?shù)據(jù)"+(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中生成一個(gè)隨機(jī)數(shù)
* @return 隨機(jī)生成的數(shù)字組合字符串: data1,data2,data3,...dataN
*/
public String getRandomNum(int mode){
String strRandomNum = "";
int maxI = 7;
//根據(jù)模式(天定踱、周棍潘、月)確定要繪制的折線圖
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中生成一個(gè)隨機(jī)數(shù)
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;
}
/**
* 發(fā)送數(shù)據(jù)
* @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);
}
}