最新要闻
- 江苏女孩中考742分报考师范专科引争议 家长:不差钱 7年贯通培养有编制
- 离谱!智己L7后尾灯可以玩“魂斗罗” 奥迪灯厂也得服
- 售价17.59万起 全新雪弗兰迈锐宝XL上市 这内饰你能接受吗?
- 顺河镇细处作手推动作风建设
- 电动轮椅上下班靠谱吗?广州明天举行听证会:事关电动自行车限行
- 广州一特斯拉闯红灯撞电瓶车致1死 另一路人擦肩而过躲过一劫
- 美国地质局调查报告:美国近一半自来水含有毒物质
- 别买白色、黑色汽车了:保值率堪忧!二手亏出血
- 分别配齐苹果、OPPO和华为全家桶后:悟出一个深刻道理
- 对标传祺影豹R?奇瑞艾瑞泽8 2.0T高能版即将上市
- 瀚川智能发布100PPM全极耳大圆柱高速自动化装配整线
- 舒适透气 吸湿排汗:大嘴猴棉背心14元/件(日常24元)
- 大马拉小车的RTX 4060 Ti 16GB来了:让人看不懂
- 销量暴跌近七成 被称作“国民神车”的五菱MINI EV为啥卖不动了?
- 轻松集团马孝武:行业间需要加强协作 进行精细化的养老需求分层
- 女子找手机乘客干等3小时?东航回应:延误原因是天气及流量控制
手机

英国房地产因利率上升陷入困境 房价正以2011年来最快速度下跌

宁夏评选出上半年10名“宁夏好人” 95后消防员因敬业奉献入选
- 英国房地产因利率上升陷入困境 房价正以2011年来最快速度下跌
- 宁夏评选出上半年10名“宁夏好人” 95后消防员因敬业奉献入选
- 离婚时共同债务应该怎么处理?
- 华为云盘古大模型3.0正式发布
- 支持自动长文生成,WPS AI发布:基于大语言模型的智能办公助手
- 《街头霸王6》全球总销量突破200万份 卡普空再次为其玩家送上礼物
家电
通用曲线控件源码定制之设计实现篇(功能丰富灵活) 浮云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作为数据管理容
根据上面功能结构,设计主要类:
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 stub29 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 Listlabels) { 77 draw(canvas, paint, plotArea, labels, 0); 78 } 79 80 public void draw(Canvas canvas, Paint paint, RectF plotArea, 81 List 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 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 + xPixelsPerUnit105 * (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, orgY118 + _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 = orgY146 + _scaleFontStyle.size + _majorScaleLineLength147 + _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 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 + xPixelsPerUnit170 * (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 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 - yPixelsPerUnit236 * (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 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 - yPixelsPerUnit299 * (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 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 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 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版源码工程下载。
关键词:
-
-
-
-
通用曲线控件源码定制之设计实现篇(功能丰富灵活) 浮云E绘图
rust 自动化测试、迭代器与闭包、智能指针、无畏并发
String内存模型和Java常用方法
华为云河图KooMap:夯实数字孪生底座,点燃燎原星火
江苏女孩中考742分报考师范专科引争议 家长:不差钱 7年贯通培养有编制
离谱!智己L7后尾灯可以玩“魂斗罗” 奥迪灯厂也得服
售价17.59万起 全新雪弗兰迈锐宝XL上市 这内饰你能接受吗?
顺河镇细处作手推动作风建设
电动轮椅上下班靠谱吗?广州明天举行听证会:事关电动自行车限行
广州一特斯拉闯红灯撞电瓶车致1死 另一路人擦肩而过躲过一劫
线性表
美国地质局调查报告:美国近一半自来水含有毒物质
别买白色、黑色汽车了:保值率堪忧!二手亏出血
分别配齐苹果、OPPO和华为全家桶后:悟出一个深刻道理
对标传祺影豹R?奇瑞艾瑞泽8 2.0T高能版即将上市
【补】托勒密定理
瀚川智能发布100PPM全极耳大圆柱高速自动化装配整线
舒适透气 吸湿排汗:大嘴猴棉背心14元/件(日常24元)
大马拉小车的RTX 4060 Ti 16GB来了:让人看不懂
销量暴跌近七成 被称作“国民神车”的五菱MINI EV为啥卖不动了?
数据交换不失控:华为云EDS,让你的数据你做主
轻松集团马孝武:行业间需要加强协作 进行精细化的养老需求分层
女子找手机乘客干等3小时?东航回应:延误原因是天气及流量控制
职场第一课!大学生暑假涌向工厂流水线:有的目标是挣台iPad
呵护牙龈不含氟 国货品牌田七牙膏:6支到手29.9元 赠牙刷
适合招待客人的家常菜?
当年理科状元:余承东将出任母校霍邱二中鸿蒙班名誉班主任
AMD发布23.7.1 WHQL驱动:RX 7000显卡功耗过高bug终于修复了
张朝阳回应曾患焦虑症并已痊愈:靠心理学彻底治好 自己状态更好了
非常简易的还原分数方法
什么水平?巴黎新援李刚仁曾一条龙远射攻破皇马大门
我国一千年玻璃鸭是全球限量款:仅一件 用途成谜
《真人快打1》裂口女新造型倍受好评:极致恐怖獠牙
给AMD Zen5下马威!Intel 14代酷睿处理器整装待发:性能喜人
启辰发布最新产品计划 每年将推出至少2款新能源车型
湖北启动针对五峰县的省级地质灾害三级响应
美国加州一架飞机失事 现场一片狼藉:机上6名乘客遇难
世界第一! 上半年全国机动车达4.26亿辆 驾驶员超5亿
选读SQL经典实例笔记03_DML和元数据
新疆维吾尔自治区喀什市2023-06-26 01:25发布大风蓝色预警
内存SSD价格低谷已至!但先别贪便宜
健身房被淹教练只能抱出来蛋白粉:损失在100万左右
21年前硫酸泼熊清华大学生任职中科院引热议 专家:没必要看过去
中国工程院院士:我们算力超过时 GDP也可以超过美国了
拉脱维亚新总统宣誓就职
必看的节奏!《碟中谍7》口碑炸翻:阿汤哥从影42年来历史最佳
科技高管们太难了:借酒浇愁、吃药止痛
曝OLED版MacBook Pro生产难度太大:跳票了
Android架构组件LiveData
旅宋壹城壹旅礼品福卡商城,百业赋能专家!
固态价格暴跌:什么样的性价比最高?
国科大录取通知书含7颗大豆:组成“北斗七星”
多地冲40℃!南北高温区将连成一片直到下周 网友直呼热哭了
超级巨大的失误深圳门将摘球脱手,朴成笑纳大礼打空门进球
宝马电车没人买?半年卖出4.5万台:月均7500辆羡煞新势力
电影《长安三万里》上映:首日票房破亿
取代mini LED/LCD!iPad Pro拥抱OLED:明年初量产
痛苦了好几年,终于知道如何与孩子相处
摆钟论是哪位科学家的著作?摆钟的优点缺点和原理是什么?
非法请求是什么意思?非法请求怎么解决?
卡萨帝空调欲创新吉尼斯世界纪录:24小时除湿200斤水
先救女友情侣送完锦旗后订婚了 网友:祝百年好合
使出浑身解数是什么意思?使出浑身解数的近义词有哪些?
峨眉派的创始人是谁?峨眉派在哪个地方?
national是什么牌子的空调?national空调遥控器代码
【全网最细】mybatis-plus的java.lang.IllegalStateException: Failed to load ApplicationCo
售价5400元 宝马推出摩托车智能墨镜:50度高温也能用
电动车火灾频发!背后原因揭开
一瓶也包邮!海南春光一口鲜气椰汁大促:2斤9.9元速囤
ChatGPT被起诉索赔30亿!16人匿名状告OpenAI
阿迪达斯沐浴露650毫升到手25元:持久留香
银行卡盗窃一万元要判几年?银行卡盗窃罪量刑标准金额
酒店式公寓的中央空调是独立的吗?酒店式公寓的产权是多久?
重庆市如何收取房产税?重庆市房产税实施细则2023年
proe是什么软件?proe和creo的区别是什么?
php主要用于什么开发?php在云计算中的应用有哪些?
“他们好辛苦,娃娃很能干!”强降雨致山体滑坡 救援队翻山蹚水转移村民
小米继续推进降本增效:成立降本增效专项组 CFO林世伟挂帅
乘客被熊孩子薅头发弹脑壳反遭吼 弹你又怎样:网友看不下去 双方最后和解
中汽协删除16家车企承诺“不打价格战”条款:自主定价、公平竞争
常用的注意力机制模块(SE、CBAM)
伤寒论视频讲座 1一70全集郝万山(伤寒)
猴痘可能使人短期毁容:多地多人确诊 如何避免感染猴痘病毒?
世卫认定的超级致癌物黄曲霉菌!科普:比砒霜毒68倍、你身边就有
从零用python flask框架写一个简易的网站
Python多任务教程:进程、线程、协程
python中zeros函数和ones函数的详细用法
总投资约306亿元 南阳105个项目纳入2023年全省卫生健康“三个一批”项目
男子人肉占车位 雷克萨斯直接倒车撞 网友:解气但不提倡
49db智能降噪!iQOO TWS 1评测:戴上它 整个世界都安静了
被污名化太久!腾讯张立军:游戏强力推动芯片、AI等技术发展
2999元智商税“圾皇” 买完要被朋友嘲笑两年半
[初等数论]欧几里得算法:最大公因数/公因式求解算法的数学证明与程序实现
子/次模 (Submodular)、超模 (Supermodular)和模(Modular)函数
近期,四大生肖事业连走上坡路,收入节节高升,财运亨通
把充电速度带入“5G时代” 理想纯电车型搭载5C电池:不到十分钟续航400km
iPad mini唯一对手!新款联想拯救者Y700性能确认:搭载骁龙8+
李玟演唱《战歌》竟成绝唱 《斗罗大陆2》动画片头缅怀
都不买英伟达难受了:RTX 4080大降价 首次跌破1000美元!降到多少你会买?
我国新能源汽车达1620万辆 仅汽车保有量1/20 增长潜力巨大