本文实例为大家分享了Android自定义条形对比统计图的具体代码,供大家参考,具体内容如下
一、测试截图
二、实现方法
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308package com.xtravel.widget; import java.util.Timer; import java.util.TimerTask; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.view.View; /** * @name 自定义数据中心旅客分析变化趋势图 * @Descripation <br> * 1、根据用户提供的数据(两组float[]数)智能绘制数据的对比条形图。<br> * 2、绘制图表信息:边框、表名、建立二维坐标系、刻度数量、刻度值、单位、网络线、图例、数据系列。<br> * 3、其中Y轴的最大刻度值是用户所提供数据中float[]的最大值,分度值是最大刻度值与刻度数目的比。<br> * 4、绘制用户数据对比条形图:启动线程,遍历数组值,不断在原图上刷新。<br> * @author Freedoman * @date 2014-9-17 * @version 1.0 */ public class DataCenterCustomBarChart extends View { // 框架起点坐标、中心坐标、宽高 private final int FRAME_X = 20; private final int FRAME_Y = 20; private final int FRAME_WIDTH = 1000; private final int FRAME_HEIGHT = 350; private final int FRAME_CENTER_X = FRAME_WIDTH / 2 + FRAME_X; private final int FRAME_CENTER_Y = FRAME_HEIGHT / 2 + FRAME_Y; // 二维坐标系原点坐标 private final int ORIGIN_X = FRAME_X + 100; private final int ORIGIN_Y = FRAME_Y + FRAME_HEIGHT - 100; // XY轴终点坐标 private final int XAXIS_X = FRAME_X + FRAME_WIDTH - 200; private final int XAXIS_Y = ORIGIN_Y; private final int YAXIS_X = ORIGIN_X; private final int YAXIS_Y = FRAME_Y + 50; // XY轴刻度数 private int countX; private int countY; // XY轴分度值、真实数据分度值 private float intervalX; private float intervalY; private float intervalPress; // 单位名称 private String nameX; private String nameY; // 图表名称 private String chartTitle; // 用户数据 private int[] data1; private int[] data2; private int currentPosition; /** * 用户建立图表 * * @param context * @param chartTitle * 表名称 * @param nameXAxis * X轴单位 * @param nameYAxis * Y轴单位 * @param countY * Y轴刻度数目 * @param thisYearWeekPerson * 用户数据 * @param lastYearWeekPerson * 用户数据 */ public DataCenterCustomBarChart(Context context, String chartTitle, String nameXAxis, String nameYAxis, int countY, int[] thisYearWeekPerson, int[] lastYearWeekPerson) { super(context); this.chartTitle = chartTitle; // x轴刻度数量以用户数据最大数据为依据,y轴刻度数量由用户来指定 this.countX = thisYearWeekPerson.length > lastYearWeekPerson.length ? thisYearWeekPerson.length : lastYearWeekPerson.length; this.countY = countY; this.nameX = nameXAxis; this.nameY = nameYAxis; this.data1 = thisYearWeekPerson; this.data2 = lastYearWeekPerson; // 计算XY轴分度值 = 轴长/刻度数 this.intervalX = (XAXIS_X - ORIGIN_X) / countX; this.intervalY = (ORIGIN_Y - YAXIS_Y) / countY; // 计算用户数据分度值 = 用户数据最大值/ 刻度数 float max1 = findMaxData(thisYearWeekPerson); float max2 = findMaxData(lastYearWeekPerson); this.intervalPress = (max1 > max2 ? max1 : max2) / countY; // startDrawDynomicBar(); } /** * 动态绘制任务 */ public void freshDynomicBar() { final Timer timer = new Timer(); TimerTask timerTask = new TimerTask() { @Override public void run() { currentPosition++; postInvalidate(); if (currentPosition == countX) { timer.cancel(); } } }; timer.schedule(timerTask, 100, 800); } /** * 绘制图表 */ @SuppressLint("DrawAllocation") public void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.WHITE); Paint paint = new Paint(); initAXIS(canvas, paint, chartTitle); drawDynamicBar1(canvas, paint, data1); drawDynamicBar2(canvas, paint, data2); } /** * 初始化图表基本信息<br> * 表名、坐标系、刻度数量、刻度值、网络线、图例、数据系列 * * @param canvas */ private void initAXIS(Canvas canvas, Paint paint, String chartTitle) { // 画边框 paint.setColor(Color.GRAY); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(6); canvas.drawRect(FRAME_X, FRAME_Y, FRAME_WIDTH, FRAME_HEIGHT, paint); // 画坐标轴 paint.setColor(Color.BLACK); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5); // X轴及方向箭头 canvas.drawLine(ORIGIN_X, ORIGIN_Y, XAXIS_X, XAXIS_Y, paint); canvas.drawLine(XAXIS_X, XAXIS_Y, XAXIS_X - 10, XAXIS_Y - 10, paint); canvas.drawLine(XAXIS_X, XAXIS_Y, XAXIS_X - 10, XAXIS_Y + 10, paint); // Y轴及方向箭头 canvas.drawLine(ORIGIN_X, ORIGIN_Y, YAXIS_X, YAXIS_Y, paint); canvas.drawLine(YAXIS_X, YAXIS_Y, YAXIS_X - 10, YAXIS_Y + 10, paint); canvas.drawLine(YAXIS_X, YAXIS_Y, YAXIS_X + 10, YAXIS_Y + 10, paint); // 图表名称(2014年五月第一周) paint.setColor(Color.BLACK); paint.setStyle(Paint.Style.FILL); paint.setTextSize(20);// 设置字体大小 paint.setStrokeWidth(2); canvas.drawText(chartTitle, FRAME_CENTER_X - 100, FRAME_Y + 30, paint); // 绘制数据系列20*20矩形(今年、去年) paint.setColor(Color.CYAN); canvas.drawRect(FRAME_WIDTH - 100, FRAME_CENTER_Y - 30, FRAME_WIDTH - 70, FRAME_CENTER_Y, paint); canvas.drawText("今年", FRAME_WIDTH - 60, FRAME_CENTER_Y, paint); paint.setColor(Color.MAGENTA); canvas.drawRect(FRAME_WIDTH - 100, FRAME_CENTER_Y, FRAME_WIDTH - 70, FRAME_CENTER_Y + 30, paint); canvas.drawText("去年", FRAME_WIDTH - 60, FRAME_CENTER_Y + 30, paint); // 画网格线 paint.setColor(Color.GRAY); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(2); // 横线(从x轴依次向上画) for (int i = 0; i <= countY; i++) { canvas.drawLine(ORIGIN_X, ORIGIN_Y - i * intervalY, XAXIS_X, ORIGIN_Y - i * intervalY, paint); } // 竖线(从y轴依次向右画) for (int i = 0; i <= countX; i++) { canvas.drawLine(ORIGIN_X + i * intervalX, ORIGIN_Y, ORIGIN_X + i * intervalX, YAXIS_Y, paint); } // X轴刻度值(沿X轴方向1、2、3...),轴名称 paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.FILL); paint.setStrokeWidth(2); paint.setTextSize(30); for (int i = 0; i <= countX; i++) { canvas.drawText("" + i, ORIGIN_X + i * intervalX, ORIGIN_Y + 50, paint); } paint.setTextSize(20); // Y轴刻度值(沿Y轴方向,用户提供的数据)轴名称 for (int i = 1; i <= countY; i++) { canvas.drawText("" + (int) (i * intervalPress), ORIGIN_X - 80, ORIGIN_Y - i * intervalY + 5, paint); } paint.setTextSize(20); canvas.drawText("(" + nameX + ")", XAXIS_X + 40, XAXIS_Y + 50, paint); canvas.drawText("(" + nameY + ")", YAXIS_X - 30, YAXIS_Y - 20, paint); } /** * 绘制data1变化趋势线 <br> */ @SuppressLint("ResourceAsColor") private void drawDynamicBar1(Canvas canvas, Paint paint, int[] data) { float curRectX_data1 = ORIGIN_X + intervalX - 30; float curRectY_data1; for (int i = 1; i < currentPosition; i++, curRectX_data1 += intervalX) { // 绘制data1的动态条形 paint.setColor(Color.CYAN); curRectY_data1 = data[i - 1] / intervalPress * intervalY; canvas.drawRect(curRectX_data1, ORIGIN_Y - curRectY_data1, curRectX_data1 + 30, ORIGIN_Y, paint); } } /** * 绘制data2变化趋势线 */ @SuppressLint("ResourceAsColor") private void drawDynamicBar2(Canvas canvas, Paint paint, int[] data) { float curRectX_data2 = ORIGIN_X + intervalX; float curRectY_data2; for (int i = 1; i < currentPosition; i++, curRectX_data2 += intervalX) { // 绘制data2的动态条形 paint.setColor(Color.MAGENTA); curRectY_data2 = data[i - 1] / intervalPress * intervalY; canvas.drawRect(curRectX_data2, ORIGIN_Y - curRectY_data2, curRectX_data2 + 30, ORIGIN_Y, paint); } } /** * 查找数组的最大值 * * @param data * @return float */ private int findMaxData(int[] data) { int max = data[0]; for (int i = 1; i < data.length; i++) { if (data[i] > max) { max = data[i]; } } return max; } /** * 计算今年游客数相对去年的增长率 * * @return float 增长率百分数 */ public float getGrowthRate() { float sumYear = 0, sumLastYear = 0; for (int i = 0; i < data1.length; i++) { sumYear += data1[i]; sumLastYear += data2[i]; } return (sumYear - sumLastYear) / sumLastYear * 100; } /** * 统计一周总人数 * * @return int 人数 */ public int getSumWeek() { int sum = 0; for (int i = 0; i < data1.length; i++) { sum += data1[i]; } return sum; } /** * 统计一周平均每天旅客数量 * * @return int */ public int getAverageWeek() { return getSumWeek() / data1.length; } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持靠谱客。
最后
以上就是忧虑小馒头最近收集整理的关于Android自定义条形对比统计图的全部内容,更多相关Android自定义条形对比统计图内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复