Android图表绘制
来源:互联网 发布:mysql高级编程 编辑:程序博客网 时间:2024/06/06 00:18
由于最新项目需要用到图表显示数据,所以参考网上的资源,写了一个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); }}
demo下载地址:http://download.csdn.net/detail/oqinyou/9492870
2 0
- Android 图表绘制
- Android 图表绘制
- Android 图表绘制
- Android 图表绘制
- Android自定义绘制图表
- Android图表绘制
- [Android]Android 如何绘制图表
- android图形图表绘制控件
- android绘制图表(二)
- android开发之图表绘制
- Android使用MPAndroidChart绘制图表
- android中绘制各种图表
- android使用mpandroidchart绘制图表
- Android图表绘制之MPAndroidChart
- Android图表的绘制基础知识
- Android实现图表绘制和展示
- Android实现 图表 绘制和展示
- Android实现图表绘制和展示
- libpng warning: iCCP: Not recognizing known sRGB profile that has been edited
- 【Redis源码剖析】 - Redis数据类型之列表List
- C#第五次上机
- ROC和AUC介绍
- LeetCode 175 -Combine Two Tables ( MYSQL )
- Android图表绘制
- HDOJ 1081 To The Max
- LeetCode #9 Palindrome Number C# Solution
- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- POJ1149 PIGS
- CAP原理
- BlockingQueue
- hibernate对连接池的支持
- 一些linux的基本操作