1 // 作者:浮云绘图
2 // 联系:QQ 316868127
3
4 public abstract class AbstractAxis {
5 public enum EnAxisType // 坐标轴类型
6 {
7 X, // 主X轴
8 Y, // 主Y轴
9 X2, // 副X轴
10 Y2, // 副Y轴
11 All, // 所有轴
12 };
13
14 public enum EnAxisTitleAlign // 轴名称文字位置
15 {
16 Center, // 居中
17 Away, // 轴最大值方向对齐
18 Near, // 轴最小值方向对齐
19 };
20
21 public enum EnTickerMode { // 刻度线模式
22 Above, // 轴上
23 Underside, // 轴下
24 Both, // 轴上下
25 };
26
27
28 protected EnAxisType _type;
29 protected boolean _visible = false;
30 // protected boolean _reversed = false;
31 // protected boolean _autoScale = true;
32 protected double _dMax; // 最大值
33 protected double _dMin; // 最小值
34 // protected double _dMajor; // 大刻度间隔
35 protected double _origin = Double.MAX_VALUE; // XY轴起点
36 protected boolean _autoOrigin = true;
37
38 // 标题--abcd
39 private int k = 3432; //svn tst
40 protected String _title = "Axis";
41 protected FontStyle _titleFontStyle;
42 // protected EnAxisTitleAlign _titleAlign;
43 protected boolean _titleVisible = true;
44
45 // 轴线
46 protected LineStyle _axisLineStyle;
47
48 // 刻度线
49 protected LineStyle _scaleLineStyle;
50 protected int _majorScaleLineLength = 5; // 大刻度线长
51 protected int _scaleLabelToValueLength = 2;
52 protected boolean _showTickMarks = true ;
53
54 // 刻度值
55 protected float _scaleValeAngle;
56 protected FontStyle _scaleFontStyle;
57 protected int _scaleValueColor = Color.BLACK;
58 protected boolean _showLabels = true;
59
60 // 网格
61 protected Grid _grid;
62
63 protected AbstractAxis() {
64 _dMax = Double.MIN_VALUE;
65 _dMin = Double.MAX_VALUE;
66
67 _titleFontStyle = new FontStyle(11, Color.BLACK);
68 _axisLineStyle = new LineStyle(1, Color.BLACK);
69 _scaleLineStyle = new LineStyle(1, Color.BLACK);
70 _scaleFontStyle = new FontStyle(10, Color.CYAN);
71
72 _grid = new Grid();
73 }
74
75 public void draw(Canvas canvas, Paint paint, RectF plotArea,
76 List<Double> labels) {
77 draw(canvas, paint, plotArea, labels, 0);
78 }
79
80 public void draw(Canvas canvas, Paint paint, RectF plotArea,
81 List<Double> labels, float originOffset) {
82 if (!_visible) {
83 return;
84 }
85
86 Rect txtRect = new Rect();
87 String txtLable = "";
88 float position = 0;
89
90 paint.setStyle(Style.FILL);
91 switch (_type) {
92 case X: {
93 double xPixelsPerUnit = plotArea.width()
94 / (WorldToPhysical(_dMax) - WorldToPhysical(_dMin));
95
96 // 网格 刻度线 标签 轴线 名称
97 List<Double> axisLabels = labels;
98 boolean showGridY = _grid.getVisible();
99 float orgY = plotArea.bottom - originOffset;
100 int length = axisLabels.size();
101
102 for (int i = 0; i < length; i++) {
103 double label = axisLabels.get(i);
104 float xLabel = (float) (plotArea.left + xPixelsPerUnit
105 * (WorldToPhysical(label) - WorldToPhysical(_dMin)));
106
107 paint.setStyle(Style.STROKE);
108 if (showGridY) {
109 paint.setStrokeWidth(_grid.getMarjorGridLineStyle().width);
110 paint.setColor(_grid.getMarjorGridLineStyle().color);
111 canvas.drawLine(xLabel, plotArea.bottom, xLabel,
112 plotArea.top, paint);
113 }
114 if (_showTickMarks) {
115 paint.setStrokeWidth(_scaleLineStyle.width);
116 paint.setColor(_scaleLineStyle.color);
117 canvas.drawLine(xLabel, orgY, xLabel, orgY
118 + _majorScaleLineLength, paint);
119 }
120 if (_showLabels) {
121 paint.setStyle(Style.FILL);
122 paint.setColor(_scaleValueColor);
123 paint.setTextSize(_scaleFontStyle.size);
124 txtLable = getValueFormat(label);
125 paint.getTextBounds(txtLable, 0, txtLable.length(), txtRect);
126
127 position = orgY + _scaleFontStyle.size + _majorScaleLineLength + _scaleLabelToValueLength;
128 if (!_showTickMarks) {
129 position -= _majorScaleLineLength/* + _scaleLabelToValueLength*/;
130 }
131
132 canvas.drawText(txtLable, xLabel - txtRect.width() / 2, position, paint);
133 }
134 }
135 paint.setStyle(Style.STROKE);
136 paint.setColor(_axisLineStyle.color);
137 paint.setStrokeWidth(_axisLineStyle.width);
138 canvas.drawLine(plotArea.left, orgY, plotArea.right, orgY, paint);
139
140 paint.setStyle(Style.FILL);
141 paint.setColor(_titleFontStyle.color);
142 paint.setTextSize(_titleFontStyle.size);
143
144 Rect rect = GraphUtil.getBounds(paint, _title);
145 position = orgY
146 + _scaleFontStyle.size + _majorScaleLineLength
147 + _scaleLabelToValueLength + _titleFontStyle.size;
148 if (!_showTickMarks) {
149 position -= _majorScaleLineLength/* + _scaleLabelToValueLength*/;
150 }
151 if (!_showLabels){
152 position -= _scaleFontStyle.size;
153 }
154 canvas.drawText(_title, plotArea.right - rect.width() - 5, position, paint);
155 }
156 break;
157 case X2: {
158 double xPixelsPerUnit = plotArea.width()
159 / (WorldToPhysical(_dMax) - WorldToPhysical(_dMin));
160
161 // 网格 刻度线 标签 轴线 名称
162 List<Double> axisLabels = labels;
163 boolean showGridY = _grid.getVisible();
164 float orgY = plotArea.top;
165 int length = axisLabels.size();
166
167 for (int i = 0; i < length; i++) {
168 double label = axisLabels.get(i);
169 float xLabel = (float) (plotArea.left + xPixelsPerUnit
170 * (WorldToPhysical(label) - WorldToPhysical(_dMin)));
171
172 paint.setStyle(Style.STROKE);
173 if (showGridY) {
174 paint.setStrokeWidth(_grid.getMarjorGridLineStyle().width);
175 paint.setColor(_grid.getMarjorGridLineStyle().color);
176 canvas.drawLine(xLabel, plotArea.bottom, xLabel,
177 plotArea.top, paint);
178 }
179 if (_showTickMarks) {
180 paint.setStrokeWidth(_scaleLineStyle.width);
181 paint.setColor(_scaleLineStyle.color);
182 canvas.drawLine(xLabel, orgY - _majorScaleLineLength,
183 xLabel, orgY, paint);
184 }
185 if (_showLabels) {
186 paint.setStyle(Style.FILL);
187 paint.setColor(_scaleValueColor);
188 paint.setTextSize(_scaleFontStyle.size);
189 txtLable = getValueFormat(label);
190 paint.getTextBounds(txtLable, 0, txtLable.length(), txtRect);
191
192 position = orgY - _majorScaleLineLength- _scaleLabelToValueLength;
193 if (!_showTickMarks) {
194 position += _majorScaleLineLength/* + _scaleLabelToValueLength*/;
195 }
196
197 canvas.drawText(txtLable, xLabel - txtRect.width() / 2, position, paint);
198 }
199 }
200 paint.setStyle(Style.STROKE);
201 paint.setColor(_axisLineStyle.color);
202 paint.setStrokeWidth(_axisLineStyle.width);
203 canvas.drawLine(plotArea.left, orgY, plotArea.right, orgY, paint);
204
205 paint.setStyle(Style.FILL);
206 paint.setColor(_titleFontStyle.color);
207 paint.setTextSize(_titleFontStyle.size);
208 Rect rect = GraphUtil.getBounds(paint, _title);
209
210 position = orgY - _scaleFontStyle.size - _majorScaleLineLength - _scaleLabelToValueLength;
211 if (!_showTickMarks) {
212 position += _majorScaleLineLength/* + _scaleLabelToValueLength*/;
213 }
214 if (!_showLabels){
215 position += _scaleFontStyle.size;
216 }
217
218 canvas.drawText(_title, plotArea.right - rect.width() - 5, position, paint);
219
220 }
221 break;
222
223 case Y: {
224 double yPixelsPerUnit = plotArea.height()
225 / (WorldToPhysical(_dMax) - WorldToPhysical(_dMin));
226
227 // 网格 刻度线 轴线 标签 名称
228 List<Double> axisLabels = labels;
229 boolean showGridX = _grid.getVisible();
230 float orgX = plotArea.left + originOffset;
231 int length = axisLabels.size();
232
233 for (int i = 0; i < length; i++) {
234 double label = axisLabels.get(i);
235 float yLabel = (float) (plotArea.bottom - yPixelsPerUnit
236 * (WorldToPhysical(label) - WorldToPhysical(_dMin)));
237
238 paint.setStyle(Style.STROKE);
239 if (showGridX) {
240 paint.setStrokeWidth(_grid.getMarjorGridLineStyle().width);
241 paint.setColor(_grid.getMarjorGridLineStyle().color);
242 canvas.drawLine(plotArea.left, yLabel, plotArea.right,
243 yLabel, paint);
244 }
245 if (_showTickMarks) {
246 paint.setStrokeWidth(_scaleLineStyle.width);
247 paint.setColor(_scaleLineStyle.color);
248 canvas.drawLine(orgX - _majorScaleLineLength, yLabel, orgX,
249 yLabel, paint);
250 }
251 if (_showLabels) {
252 paint.setStyle(Style.FILL);
253 paint.setColor(_scaleValueColor);
254 paint.setTextSize(_scaleFontStyle.size);
255 txtLable = getValueFormat(label);
256 paint.getTextBounds(txtLable, 0, txtLable.length(), txtRect);
257
258 position = orgX - txtRect.width() - _majorScaleLineLength - _scaleLabelToValueLength;
259 if (!_showTickMarks) {
260 position += _majorScaleLineLength/* + _scaleLabelToValueLength*/;
261 }
262 canvas.drawText(txtLable, position, yLabel + _scaleFontStyle.size / 2, paint);
263 }
264 }
265 paint.setStyle(Style.STROKE);
266 paint.setColor(_axisLineStyle.color);
267 paint.setStrokeWidth(_axisLineStyle.width);
268 canvas.drawLine(orgX, plotArea.top, orgX, plotArea.bottom, paint);
269
270 paint.setStyle(Style.FILL);
271 paint.setColor(_titleFontStyle.color);
272 paint.setTextSize(_titleFontStyle.size);
273 Rect rect = GraphUtil.getBounds(paint, _title);
274 int scaleVMaxWidth = getLablesMaxLength(paint, labels);
275
276 position = orgX - scaleVMaxWidth - _majorScaleLineLength - _scaleLabelToValueLength - 2;
277 if (!_showTickMarks) {
278 position += _majorScaleLineLength/* + _scaleLabelToValueLength*/;
279 }
280 if (!_showLabels){
281 position += scaleVMaxWidth;
282 }
283 GraphUtil.drawText(canvas, _title, position, plotArea.top + rect.width() + 5, paint, -90);
284 }
285 break;
286 case Y2: {
287 double yPixelsPerUnit = plotArea.height()
288 / (WorldToPhysical(_dMax) - WorldToPhysical(_dMin));
289
290 // 网格 刻度线 轴线 标签 名称
291 List<Double> axisLabels = labels;
292 boolean showGridX = _grid.getVisible();
293 float orgX = plotArea.right;
294 int length = axisLabels.size();
295
296 for (int i = 0; i < length; i++) {
297 double label = axisLabels.get(i);
298 float yLabel = (float) (plotArea.bottom - yPixelsPerUnit
299 * (WorldToPhysical(label) - WorldToPhysical(_dMin)));
300
301 paint.setStyle(Style.STROKE);
302 if (showGridX) {
303 paint.setStrokeWidth(_grid.getMarjorGridLineStyle().width);
304 paint.setColor(_grid.getMarjorGridLineStyle().color);
305 canvas.drawLine(plotArea.left, yLabel, plotArea.right,
306 yLabel, paint);
307 }
308 if (_showTickMarks) {
309 paint.setStrokeWidth(_scaleLineStyle.width);
310 paint.setColor(_scaleLineStyle.color);
311 canvas.drawLine(orgX, yLabel, orgX + _majorScaleLineLength,
312 yLabel, paint);
313 }
314 if (_showLabels) {
315 paint.setStyle(Style.FILL);
316 paint.setColor(_scaleValueColor);
317 paint.setTextSize(_scaleFontStyle.size);
318 txtLable = getValueFormat(label);
319 paint.getTextBounds(txtLable, 0, txtLable.length(), txtRect);
320
321 position = orgX + _majorScaleLineLength + _scaleLabelToValueLength;
322 if (!_showTickMarks) {
323 position -= _majorScaleLineLength/* + _scaleLabelToValueLength*/;
324 }
325 canvas.drawText(txtLable, position, yLabel + _scaleFontStyle.size / 2, paint);
326 }
327 }
328 paint.setStyle(Style.STROKE);
329 paint.setColor(_axisLineStyle.color);
330 paint.setStrokeWidth(_axisLineStyle.width);
331 canvas.drawLine(orgX, plotArea.top, orgX, plotArea.bottom, paint);
332
333 paint.setStyle(Style.FILL);
334 paint.setColor(_titleFontStyle.color);
335 // Rect rect = GraphUtil.getBounds(paint, _title);
336 int scaleVMaxWidth = getLablesMaxLength(paint, labels);
337
338 position = orgX + scaleVMaxWidth + _majorScaleLineLength + _scaleLabelToValueLength + 2;
339 if (!_showTickMarks) {
340 position -= _majorScaleLineLength/* + _scaleLabelToValueLength*/;
341 }
342 if (!_showLabels){
343 position -= scaleVMaxWidth;
344 }
345 GraphUtil.drawText(canvas, _title, position, plotArea.top + 5, paint, 90);
346 }
347 break;
348 default:
349 break;
350 }
351 }
352
353 public int getAxisOutLength(Paint paint, List<Double> labels) {
354 // 轴名称文本、刻度值文本、刻度线
355 int outLength = 0;
356 Rect rect = new Rect();
357
358 if (_type == EnAxisType.X || _type == EnAxisType.X2) {
359 if (_titleVisible) {
360 paint.getTextBounds(_title, 0, _title.length(), rect);
361 outLength += 1 + rect.height();
362 }
363 if (_showLabels) {
364 outLength += 1 + _scaleFontStyle.size; //getLablesMaxLength(paint, labels)
365 }
366 if (_showTickMarks) {
367 outLength += _scaleLabelToValueLength + _majorScaleLineLength;
368 }
369 } else if (_type == EnAxisType.Y || _type == EnAxisType.Y2) {
370 if (_titleVisible) {
371 paint.getTextBounds(_title, 0, _title.length(), rect);
372 outLength += 1 + rect.height(); // 轴文本逆时针转90度,否则改成rect.width()
373 }
374 if (_showLabels) {
375 outLength += 1 + getLablesMaxLength(paint, labels);
376 }
377 if (_showTickMarks) {
378 outLength += _scaleLabelToValueLength + _majorScaleLineLength;
379 }
380 }
381 return outLength;
382 }
383
384 private int getLablesMaxLength(Paint paint, List<Double> labels) {
385 int len = 0;
386 for (int i = 0; i < labels.size(); i++) {
387 double label = labels.get(i);
388 String s = getValueFormat(label);
389
390 paint.setTextSize(_scaleFontStyle.size);
391 Rect r = new Rect();
392 paint.getTextBounds(s, 0, s.length(), r);
393
394 if (len < r.width()) {
395 len = r.width();
396 }
397 }
398 return len;
399 }
400
401 public void setVisible(boolean visible) {
402 _visible = visible;
403 }
404
405 public boolean getVisible() {
406 return _visible;
407 }
408
409 public void setType(EnAxisType type) {
410 _type = type;
411 if (type == EnAxisType.X || type == EnAxisType.X2) {
412 _grid.setType(EnGridType.X);
413 } else {
414 _grid.setType(EnGridType.Y);
415 }
416 }
417
418 public EnAxisType getType() {
419 return _type;
420 }
421
422 public void setTitle(String name) {
423 _title = name;
424 }
425
426 public String getTitle() {
427 return _title;
428 }
429
430 public void setMax(double max) {
431 _dMax = max;
432 }
433
434 public double getMax() {
435 return _dMax;
436 }
437
438 public void setMin(double min) {
439 _dMin = min;
440 if (_autoOrigin) {
441 // if (_origin > _dMin) {
442 _origin = _dMin;
443 // }
444 }
445 }
446
447 public double getMin() {
448 return _dMin;
449 }
450
451 public void setOrigin(double origin) {
452 _origin = origin;
453 if (!_autoOrigin) {
454 if (_origin < _dMin) {
455 _dMin = _origin;
456 }
457 if (_origin > _dMax) {
458 _dMax = _origin;
459 }
460 }
461 }
462
463 public double getOrigin() {
464 return _origin;
465 }
466
467 public void setAutoOrigin(boolean autoOrigin) {
468 _autoOrigin = autoOrigin;
469 }
470
471 public Grid getGrid() {
472 return _grid;
473 }
474
475 public void setRange(double max, double min) {
476 _dMax = max;
477 _dMin = min;
478 }
479
480 public abstract List<Double> getLabels(double start, double end,
481 int approxNumLabels);
482
483 public abstract double[] getRealData(Object object);
484
485 public abstract double WorldToPhysical(double val);
486
487 public abstract String getValueFormat(double val);
488
489 protected boolean IsAvailPoint(double val){
490 if (val < _dMin || val > _dMax) {
491 return false;
492 }
493 return true;
494 }
495
496 }