通用曲线控件源码定制之设计实现篇(功能丰富灵活) 浮云E绘图

曲线以图形表现数据,比表格数据直观多了,在各行业得到广泛的应用。浮云E绘图长期从事工业控制和军工软件研发,擅长绘图编辑器、曲线控件等软件研发,本文开启通用曲线控件的设计到编码实现系列文章。

通用曲线,即曲线功能较丰富,可以灵活满足常用曲线支持。本系列文章针对通用曲线控件做实现,下一个系列讲针对基于时间的海量数据曲线高效实现。

 

一、曲线控件部件介绍

浮云E绘图 通用曲线控件源码设计之曲线功能部件介绍

 曲线控件一般如上图所示,包含以下部件:

0.控件描述:曲线控件区域大小、背景颜色等。支持曲线实时测量、缩放、翻页、导出打印等。

1.标题Title:标题文本内容、字体类型、字体大小、字体颜色。标题区域大小、区域背景色、区域内文字对齐(左中右上下)、文字排列角度(横/竖/斜角)、标题区域基于曲线方位(上下左右/内嵌)、是否显示。

2.网格Grid:网格向类型(横向/纵向)、网格线类型(主/次线)、是否显示(主次线)、线粗细、线型(虚实)、线颜色。

3.曲线轴(X轴和Y轴):轴向类型(X/Y)、轴主副类型(X1/X2、Y1/Y2)、轴数据类型(线性轴/指数/时间/文本轴)、轴名称(文字内容、字体颜色、字型、字号、文字对齐、文字排列),轴线(线宽、线颜色、线型、端线类型(无/实心箭头/箭头线))。实现支持双X轴、双Y轴。

4.曲线:曲线类型(线性曲线/阶梯/散点/柱状/区域曲线)、曲线颜色、线条粗细、是否标注Marker(标注类型、颜色、宽度等)、曲线数据集。

曲线数据与轴类型有对应关系。一般Y轴都是数值轴,而X轴可能是数值、时间、文本等轴。当X是时间轴、Y是数值轴时,曲线点数据格式应该时x是时间值、y是数值。

5.图例Legend:图例列表排列方式(横/纵向)、图例区域块(区域大小、背景色)、图例基于控件的方位(上下左右/内嵌)、是否显示。

图例与曲线是一一对应关系,风格类型也是一致,这样才能直观的示例。比如曲线控件有2条曲线,A曲线是红色线条+方块标注,B曲线是蓝色柱状曲线,那么图例应该也是2个,A曲线图例一条线中间+方块图例,B曲线图例蓝色方块。

6.(脚注FootNote):与标题Title类似,有的曲线需要底部一段文字备注说明,或者实时显示轴移动中的原点值。

 

二、通用曲线控件灵活功能支持

如果定制的曲线控件应用场景单一,就没必要实现过多用不到的功能细节(比如标题文字多种排列和布局);如果想定制开发一套比较通用的曲线控件源码,那么就需要兼顾多种情况。

1. 坐标轴数据类型:较常用的包含线性轴 / 指数轴 / 时间轴 / 文本轴

2. 曲线类型:较常用的包含线性曲线 / 阶梯曲线 / 散点曲线 / 柱状曲线 / 饼状占比等

3. 坐标轴主副类型:同时支持X主轴X1、X副轴X2和Y主轴X1、Y副轴X2。至少一对X和Y即可。(一般不会用多轴展示数据,对比反而不直观。多数据对比曲线,一般采用,多区域纵向排列(X-Y1,X-Y2,X-Y3...)X轴同步的方式实现,请等待下一个系列曲线详细说明。)

 

三、通用曲线控件源码软件结构设计

曲线控件功能结构图如下所示,画布View作为曲线呈现,Chart作为数据管理容

浮云E绘图通用曲线控件源码软件结构设计图

 

 根据上面功能结构,设计主要类:

1. 画布类:ChartView和SimpleView,ChartView作为通用画布,支持丰富XY多坐标系,而SimpleView实现为最简单的绘图接口,默认一些参数,使用简单。

public ChartView(AbstractChart chart) 

2.数据管理类:AbstractChart --> XY坐标系的XYChart 和 饼状图的RoundChart。

 1 // 作者:浮云绘图,擅长工控、军工等领域绘图编辑器、曲线控件定制研发
 2 // 联系:QQ 316868127
 3 
 4 public XYChart(AbstractAxis axisX, AbstractAxis axisY,AbstractAxis axisX2, AbstractAxis axisY2)
 5 public XYChart(AbstractAxis axisX, AbstractAxis axisY, null, null)
 6 
 7 
 8 public void draw(Canvas canvas, Paint paint)
 9 {
10         canvas.save();
11         canvas.clipRect(_clientArea);
12         super.calcChartArea(paint);
13 
14         // 背景
15         super.drawBackground(canvas, paint);
16 
17         // 轴、网格
18         drawAxis(canvas, paint);
19 
20         // 曲线、图例、标题
21         super.draw(canvas, paint);
22         canvas.restore();
23 }
24 
25 
26 @Override protected void drawSeries(Canvas canvas, Paint paint) 
27 {
28     // TODO Auto-generated method stub
29     for (int i = 0; i < _series.size(); i++) {
30         AbstractSeries ser = _series.get(i);
31         ser.drawLine(canvas, paint,_plotArea);
32     }
33 }
34 
35 
36 @Override protected void scroll(EnZoomOrientation orientation, double physicsOffset)
37 @Override protected void zoom(EnZoomOrientation orientation, PointD physicsCenter, double physicsScale)

 

3. 头部Header

 1 public class Header extends TextNote {
 2     private EnHeadPosition _position = EnHeadPosition.TopCenter;
 3     
 4     
 5     public Header(String title, AbstractChart parent) {
 6         super(title, parent);
 7     }
 8     public void draw(Canvas canvas, Paint paint){
 9         super.draw(canvas, paint);
10     }
11     
12     public void setPosition(EnHeadPosition position){
13         if(_position != position){
14             _position = position;
15             _parent.calcChartArea();        
16         }
17     }
18     public EnHeadPosition getPosition(){
19         return _position;
20     }
21     
22     public enum EnHeadPosition{
23         TopCenter,
24         BottomCenter,
25         LeftCenter,
26     }
27 }
28 
29 public class TextNote {
30     protected AbstractChart _parent;
31     protected boolean _visible = true;
32     protected String _title = "Header title";
33     protected FontStyle _fontStyle = new FontStyle(12, Color.BLACK);
34     
35     protected int _backColor = Color.LTGRAY;
36     protected RectF _rectF = new RectF();
37     protected boolean _isBoxShow = false;
38     protected LineStyle _boxStyle = new LineStyle(1, Color.BLUE);
39     
40     private int _paddingInV = 2;        
41     private int _paddingInH = 4;        
42     
43     public TextNote(String title, AbstractChart parent){
44         this._title = title;
45         _parent = parent;
46     }
47     public void draw(Canvas canvas, Paint paint){
48         if (!_visible) {
49             return;
50         }
51         
52         paint.setStyle(Style.FILL);
53         paint.setColor(_fontStyle.color);
54         paint.setTextSize(_fontStyle.size);
55         Rect r = new Rect();
56         paint.getTextBounds(_title, 0, _title.length(), r);
57         
58 
59         paint.setStyle(Style.FILL);
60         paint.setColor(_backColor);
61         canvas.drawRect(_rectF, paint);
62         
63 
64         float x = 0F, y = 0F;
65         x = _rectF.left + (_rectF.width() - r.width()) / 2 ;
66         y = _rectF.top + (_rectF.height() - r.height()) / 2  + r.height() - 1.5f;
67 
68         paint.setTextSize(_fontStyle.size);
69         paint.setColor(_fontStyle.color);
70         canvas.drawText(_title, x, y, paint);
71 
72 
73         if (_isBoxShow) {
74             paint.setStyle(Style.STROKE);
75             paint.setColor(_boxStyle.color);
76             paint.setStrokeWidth(_boxStyle.width);
77             canvas.drawRect(_rectF, paint);
78         }
79     }
80 
81 ......
82 }

 

4. 网格Grid

1 public class Grid {
2     private EnGridType _type = EnGridType.X;
3     private boolean _visible = true;
4     private LineStyle _majorGridLineStyle;
5     private LineStyle _minorGridLineStyle;
6 ......
7 
8 }

 

5.坐标轴:AbstractAxis --> 线性轴LinearAxis、指数轴LogAxis 、时间轴DatetimeAxis 、文本轴LabelAxis。

  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 }

 

6.曲线类:AbstractSeries --> 线性曲线LineSeries、阶梯曲线StepSeries、散点曲线ScattSeries、柱状曲线BarSeries、饼状曲线PieSeries。

 

浮云E绘图的通用曲线控件源码定制之设计实现篇就写这么多,该曲线控件功能丰富,扩展性强,有java版和C++版本,功能下一篇文章将继续写用曲线控件源码定制重点和难点,并将提供Java版源码工程下载。

posted @ 2023-07-09 09:56  浮云绘图  阅读(119)  评论(0)    收藏  举报