您的位置 首页 外汇EA指标

外汇EA编写教程:带CCANVAS类的绘图比例尺磁盘

内容目录 介绍 1。坐标和锚定 2。表元素2.1.2.2号。实心2.3.比例2.4。刻度线2.5.图2.6。突出显示范围2.7。台销 三。功能 3.1。量规创建 3.2。仪表TCa…

内容目录

  • 介绍
  • 1。坐标和锚定
  • 2。表元素2.1.2.2号。实心2.3.比例2.4。刻度线2.5.图2.6。突出显示范围2.7。台销
  • 三。功能
    • 3.1。量规创建
    • 3.2。仪表TCase参数
    • 3.3。仪表校准参数
    • 3.4。仪表标记参数
    • 3.5。仪表标签字体
    • 3.6。仪表组图例参数
    • 3.7。仪表设定范围参数
    • 3.8。仪表设置指针参数
    • 3.9。轨距重绘
    • 3.10。计量新值
    • 3.11。量规删除
    • 3.12。仪表计算位置
    • 3.13。仪表重新定位
  • 4。枚举
    • 4.1。枚举大小写边框样式
    • 4.2。枚举CaseSype风格
    • 4.3。枚举仪表图例
    • 4.4。枚举标记样式
    • 4.5。枚举多尺度
    • 4.6。枚举中心样式
    • 4.7。枚举指针填充
    • 4.8。枚举中继模式
    • 4.9。枚举缩放样式
    • 4.10。枚举大小
  • 5。宏替换
  • 6。修改ccanvas类
    • 6.1。使用消除混叠算法绘制段落
    • 6.2。用边缘消除混叠填充区域
  • 7。应用程序
    • 7.1。当前利润指标
    • 7.2。刻度盘指示器
  • 8。资源强度评估
  • 结论

介绍

这一切都是从我第一次通过CCANVAS课程认识到自己的时候开始的。当我用它来练习时,我突然想到用它来画一个表盘。我的第一个拨号盘很粗糙,但最终它们都添加了新的元素,让人赏心悦目。因此,我现在有了一个小的库,可以用简单易行的方式向指示器或EA添加拨号。在本文中,我们将考虑到表盘的结构,熟悉绘制和设置视觉外观的必要功能,并评估资源的强度。

刻度表盘

传说。1。校准刻度盘

1。坐标和锚定

表定位有两种类型:绝对和相对。

在绝对定位的情况下,坐标表示自定位点X和Y轴上像素的距离。

在相对定位的情况下,根据指定的相对定位类型创建坐标原点。当选择垂直类型时,原点在参考对象的下方或上方(如果分别选择锚定边或底边)。选择垂直类型时,它位于定位点角方向的左侧或右侧。在这种情况下,指定的坐标表示与原点的偏移。正偏移使对象远离引用对象。在负偏移的情况下,对象占用参考对象。

引用对象可以表示为另一个拨号对象。至关重要的是,这两个对象将具有相同的锚角。

传说。2描述了相对定位的示例。

相对定位

传说。2。刻度盘的相对位置

让我们检查每个拨号的设置:

  • 拨“GG01”:禁止相对定位。水平偏移-40,垂直偏移-40。
  • 刻度盘“GG02”:相对定位-水平,参考对象-GG01。从坐标原点(A点)水平偏移15,垂直偏移0。
  • 刻度盘“GG03”:相对位置-垂直,参考对象-GG01。坐标原点(B点)水平偏移-0,垂直偏移-15。
  • 刻度盘“GG04”:相对位置-垂直,参考对象-GG02。坐标原点(C点)水平偏移-50,垂直偏移-15。

如果图表上有几个带刻度盘的指示器,相对位置有利于输入设置。如果您决定更改一个拨号的大小,其他拨号的坐标将自动重新计算。

函数gaugeCreate()设置位置类型和坐标。

2。表元素

表盘由两种图形对象组成。一个称为刻度层,另一个称为表面针层。两种类型的图形对象具有相同的坐标。表面针层在刻度层之上。然后在参数中输入拨号集的名称作为这两种对象的前缀。例如,如果刻度盘名称为“Gauge01”,则刻度层将称为“Gauge01_s”,销层将称为“Gauge01_n”。

图3描述了表盘的结构。

图例.3. 表盘结构

传说。三。表结构

比例层包括:

  • 边框(1)
  • 刻度标记(5、6、7)
  • 校准标签(4)
  • 突出显示范围(2,12)
  • 图形(3、10、11)

插图通过使用区分:

  • 表说明(3)
  • 计量单位(11)
  • 电流值(10)
  • 刻度标签倍数(略)

比例尺分为:

  • 主体(7)
  • 培养基(5)
  • 未成年人(6)

只有主比例点有标签。缩放步骤设置为数值。中等刻度步长是根据指定主刻度之间的中等刻度数计算的。次要刻度步长是根据指定的中等刻度之间的次要标记数计算的。可省略二级和中等规模。

表面针层包括:

  • 手表针(8)
  • 台针中心(9)

2.1。大小

图3描述了一些刻度盘元件的尺寸:

  • D-刻度盘尺寸,对应刻度盘外轮廓的直径
  • B边界尺寸
  • G边界和比例元素之间的空间大小
  • C-针中心的尺寸。

笔记。只有刻度盘直径以像素(图例中的D)为单位设置。3)。所有其他元素和字体都以条件单位设置,它们的大小以直径的百分比计算。这样可以很容易地放大和缩小。如果直径发生变化,所有其他尺寸将按比例重新计算。计算系数列在宏替换部分,用户可以修改。

2.2。实体形状

有两种表盘形状:圆形和扇形。如果比例角小于180度,则扇形更方便。

表盘形状

传说。4。表盘形状

图4描述了一个圆形刻度盘(A)和两个扇形刻度盘(B、C)。函数GaugeSetcaSeparatometers()用于设置所需的实体形状。

2.3。规模

这是表盘的一个非常重要的元件。数据可读性取决于其显示。规模不应该太复杂,但同时,它必须能够充分反映信息。应特别注意尺度极值的选择和主要标志物的步长。功能GaugeScaleParameters()允许您设置刻度范围、旋转和极值(最小值和最大值)。最小值可以是左(顺时针)或右(逆时针)。

标度范围是两个标度的极值之间的半径向量形成的扇形中包含的角度。其演示如图5所示。

刻度范围

传说。5。尺度范围

刻度盘旋转是刻度盘中心向上的垂直线,它偏离刻度范围的平分点。其演示如图6所示。

刻度旋转角度

Tully。6。刻度旋转角度

刻度范围角度和旋转角度的组合可以帮助您以非常灵活的方式设置刻度盘的外观。传说。4(c)表示刻度盘旋转90度和45度。

最大和最小刻度值是重要参数,应根据显示变化值的允许范围选择。为了方便起见,可以省略零标记。如果从400更改为600,零比例将不会绘制任何点。传说。7描述了最大和最小刻度值的示例。

最大和最小刻度值

传说。7。最大和最小刻度值

  • a)顺时针从0到500的值
  • b)顺时针-200至400
  • c)从-400到0的顺时针值
  • d)值从500到0,逆时针
  • e)从200到800,顺时针
  • f)值从0到-800,逆时针

2.4。校准线

比例标记设置为选定标记的大小和排列。

具体如下:

  • 天平的内边缘
  • 刻度外缘
  • 核心

传说。8描述了比例标记排列的示例:

  • A中心
  • B内边缘
  • C外边缘

功能GaugeSetmarkParameters()用于设置。

标记的标记位置参考比例设置,并使用GaugeSTScaleParameters()功能进行调整。

传说。8(a)描述了标度内标签定位的示例,图例。8(b)和8(c)-秤外。

建议使用倍数,所有显示值将除以一个系数,这样标签在刻度上不会占用太多空间。倍数可以在0.0001到10000之间。传说。4(c)描述了一个等于100的应用程序乘数的示例,它允许用标签中的一个数字替换原来的三个数字。图例1描述了我们使用等于0.0001的倍数来显示ATR值的情况,这些值可以标记为不带小数和零值。函数gaugeScaleParameters()设置倍数。

标记和标签定位

传说。8。标记和标签位置

2.5。图表

图表旨在显示附加信息。它们可以是以下四种类型:

  • 拨号说明
  • 计量单位
  • 现值
  • 倍数

所有插图都可以隐藏。By default, only the dial description is displayed.

图形定位由角度和半径设置。角度按度数设置,其值等于从刻度盘中心到虚拟刻度盘中心的向上垂直线与图形中心线之间的角度。半径以条件单位设置。如果该值在0到10之间,则0对应于打捆针中心的半径,而10对应于磅秤的外半径。

传说。9描述了说明性的定位示例。

  • 图表“利润”(表盘说明)有以下坐标:角度-0,半径-3。
  • 图形“0.00”(当前值)具有以下坐标:角度-225,半径-4。
  • 图形“USD”(测量单位)具有以下坐标:角度215,半径8。

函数GaugeSetleGendParameters()用于设置图形参数。

图解坐标

传说。9。图形坐标

笔记。该图不固定在刻度上,其角度与刻度旋转角度无关。

2.6。亮点范围

突出显示的数据范围表示所有拨号盘的固有元素。它们有助于观察已达到紧急值或已进入某些特定范围的变化。功能GaugeStrangeParameters()最多可设置为四个突出显示。要做到这一点,您需要设置极值和高光。图1描述了一个带有两个突出显示的范围的利润指标:绿色范围从200到400,表示固定收益的倍数,橙色范围从-200到-400。这一警告的撤销幅度更大。

2.7。指针

功能仪表设置参数()设置打捆针中心和填充区域的大小。填充区域的类型会影响指示器的资源强度,例如每次数据更新后,将完全重新绘制表面针层。传说。10描述了填充区域的示例。

  • 使用消除混叠算法填充针(A)
  • 不使用消除混叠算法填充针(B)
  • 使用消除混叠轮廓,但不要填充针(C)

刻度表盘0

传说。10。台针填充法

每种方法的优缺点将在修订CCANVAS类和资源强度评估一节中描述。

三。
功能

表1列出了绘制刻度盘和设置其外观的功能。

功能 行为
仪表计算位置 计算刻度盘
的中心坐标
仪表创建 创建一个拨号
仪表删除 删除拨号
量表新值 更新管脚位置和显示值
量表重绘 重新绘制刻度盘
计重定位 更改图表
上刻度盘的位置
仪表设定箱参数 设置拨号实体参数
仪表组图例参数 设置图形参数
仪表设置标记标签字体 设置拨号标签字体
仪表设置标记参数 设置刻度盘校准参数
仪表设置指针参数 设置打捆针参数
仪表设定范围参数 设定范围参数
仪表组刻度参数 设定标度参数

表1。功能列表

让我们深入研究每个函数。它还表示我们建议在初始化时调用它们的顺序。

3.1。仪表创建

创建表盘。

bool GaugeCreate(
   string name,              // 表盘名称
   GAUGE_STR &g,             // 引用表盘结构
   int x,                    // 自锚点边角的水平缩进
   int y,                    // 自锚点边角的垂直缩进
   int size,                 // 表盘大小
   string ObjRel,            // 设置相对定位的图形对象名
   ENUM_REL_MODE rel_mode,   // 相对定位
   ENUM_BASE_CORNER corner,  // 锚点边角
   bool back,                // 对象作为背景
   uchar scale_transparency, // 刻度透明度
   uchar needle_transparency // 表针透明度 
 );

参数

姓名

&[输入]表名。用于合成拨号的每个图形对象的前缀。

& g

&[输出]表结构引用。

X

&[输入]从锚定边角度沿X轴的像素距离。在相对定位的情况下-距坐标原点的距离。

Y

&[输入]从锚定边角度沿Y轴的像素距离。在相对定位的情况下-距坐标原点的距离。

大小

&[输入]拨号大小。表示实体直径。

ObjRel

&[输入]另一个设置相对定位图形对象名称。仅用于设置相对位置。

&相对模式

&[输入]相对定位方法。它可以是枚举模式列表中的任何值。

拐角处

&[输入]图形的角点,作为图形对象的定位点。它可以是枚举基角列表中的任何值。

后退

&[输入]对象作为背景。

 缩放透明度

&[输入]缩放透明度级别。值的范围为0到255。

&针孔透明度

&[输入]Pin透明度级别。值的范围为0到255。

返回值

&如果创建了缩放层和销层对象,则返回true。否则,返回false。

3.2。仪表TCase参数

设置拨号实体参数

void GaugeSetCaseParameters(
   GAUGE_STR &g,                  // 引用表盘结构
   ENUM_CASE_STYLE style,         // 实体样式
   color ccol,                    // 实体颜色
   ENUM_CASE_BORDER_STYLE bstyle, // 边框样式
   color bcol,                    // 边框颜色
   ENUM_SIZE border_gap_size      // 边框与刻度元素之间的空间大小
);

参数

& g

&[输出]表结构引用。

风格

&[输入]实体样式。它可以是枚举大小写样式列表中的任何值。

CCOL

&[输入]纯色。

B风格

&[输入]边框样式。它可以是枚举大小写边框样式列表中的任何值。

BCOL

&[输入]边框颜色。

&间隙大小

&[输入]图例中内边界和最近比例元素(g)之间的区域。3)。它可以是枚举大小列表中的任何值。

3.3。仪表校准参数

设置比例参数。

void GaugeSetScaleParameters(
   GAUGE_STR &g,           // 引用表盘结构
   int range,              // 刻度范围
   int rotation,           // 旋转角度
   double min,             // 最小值 (左侧)
   double max,             // 最大值 (右侧)
   ENUM_MUL_SCALE mul,     // 刻度标签的倍数
   ENUM_SCALE_STYLE style, // 刻度样式
   color col,              // 刻度颜色
   bool display_arc        // 显示刻度线
);

参数

& g

&[输出]表结构引用。

范围

&[输入]刻度范围。设置半径向量形成的扇区中包含的两个刻度的极值之间的角度。值的范围为30到320度(图例。5)。

 旋转;

&[输入]刻度旋转角度(图例。6)。

最小值

&[输入]直接编号分配下的最小刻度值。

最大值

&[输入]直接编号分配下的最大刻度值。

穆尔

&[输入]比例标签的倍数。它可以是枚举mul_比例列表中的任何值。

风格

&[输入]缩放样式。它可以是枚举缩放样式列表中的任何值。

和科尔

&[输入]缩放颜色。

&显示为假

&[输入]显示刻度线。

3.4。仪表标记参数

设置比例参数。

void GaugeSetMarkParameters(  
   GAUGE_STR &g,          // 引用表盘结构
   ENUM_MARK_STYLE style, // 刻度标记的样式
   ENUM_SIZE size,        // 标记大小
   double major_tmi,      // 主要标记间隔
   int middle_tmarks,     // 主要标记之间中等标记的数量
   int minor_tmarks       // 中等标记之间次要标记的数量
);

参数

& g

&[输出]表结构引用。

风格

&[输入]缩放样式。它可以是枚举标记样式列表中的任何值。

大小

&[输入]标记大小。它可以是枚举大小列表中的任何值。

 少校

&[输入]主刻度的步长。主标签随附相关值的标签。

&中标记

&[输入]主标记之间的中间标记数可以是任意正数。没有大小限制。如果设置为0,则不显示中等标记。

& nbsp; minor_tmarks

&[输入]中等标记之间的次要标记数(如果不显示中等标记,则它是主要标记)。它可以是任何正数。没有大小限制。如果设置为0,则不会显示辅助标记。

3.5。仪表标签字体

设置缩放标记字体。

void GaugeSetMarkLabelFont(
   GAUGE_STR &g,        // 引用表盘结构
   ENUM_SIZE font_size, // 字号 
   string font,         // 字体
   bool italic,         // 斜体
   bool bold,           // 粗体
   color col            // 颜色
);

参数

& g

&[输出]表结构引用。

 字体大小

&[输入]刻度标签的大小。它可以是枚举大小列表中的任何值。

字体

&[输入]字体。

斜体字

&[输入]斜体。

大胆的;大胆的

&[输入]粗体。

和科尔

&[输入]字体颜色。

3.6。仪表组图例参数

设置图形参数

void GaugeSetLegendParameters(
   GAUGE_STR &g,         // 引用表盘结构
   ENUM_GAUGE_LEGEND gl, // 图解类型
   bool enable,          // 显示图解
   string str,           // 字符串 (或互补参数)
   int radius,           // 坐标 - 半径
   double angle,         // 坐标 - 角度
   uint font_size,       // 字号
   string font,          // 字体
   bool italic,          // 斜体
   bool bold,            // 粗体
   color col             // 颜色
);

参数

& g

&[输出]拨号结构报价

GL

&[输入]图形类型。它可以是Enum_Gauge_Legend列表中的任何值。

使能

&[输入]显示图表。

这是

&[输入]这是要显示的图例描述或图例单位类型的图形字符串。如果图形类型为Legend_Mul,则忽略参数。图形类型是图例值的小数点位置。值可以在“0”到“8”之间。任何其他值均视为“0”。例如,字符串“2”表示两位十进制数字。字符创建“hello”表示0十进制。

半径

&[输入]半径。从拨号中心到图形中心的条件单位距离(图例。9)。

夹角

&[输入]角坐标。该值等于从刻度盘中心到虚拟刻度盘中心的向上垂直线与连接图形中心的线之间的角度(图。9)。

 字体大小

&[输入]图形字体大小。

字体

&[输入]字体。

斜体字

&[输入]斜体。

大胆的;大胆的

&[输入]粗体。

和科尔

&[输入]字体颜色。

3.7。仪表设定范围参数

设置突出显示范围参数

void GaugeSetRangeParameters(
   GAUGE_STR &g, // 引用表盘结构
   int index,    // 范围索引
   bool enable,  // 显示范围
   double start, // 初始值
   double end,   // 终值
   color col     // 颜色
);

参数

& g

&[输出]表结构引用。

索引

&[输入]范围索引。值的范围可以是0到3。

使能

&[输入]显示范围。

开始

&[输入]初始值。

结束

&[输入]最终值。

和科尔

&[输入]突出显示范围颜色。

3.8。仪表设置指针参数

设置打捆针参数。

void GaugeSetNeedleParameters(
   GAUGE_STR &g,                     // 引用表盘结构
   ENUM_NCENTER_STYLE ncenter_style, // 表针中心样式
   color ncenter_col,                // 表针中心颜色
   color needle_col,                 // 表针颜色
   ENUM_NEEDLE_FILL needle_fill      // 表针填充区域方法
);

参数

& g

&[输出]表结构引用。

 取消中心样式

&[输入]笔针中心。它可以是枚举中心样式列表中的任何值。

&nCenter列

&[输入]触笔的中心颜色。

&针阀

&[输入]针颜色。

&针孔填充

&[输入]桌上针填充法。它可以是枚举指针填充列表中的任何值。

3.9。仪表重新绘制

重新绘制刻度盘。应在更改任何参数后调用函数以应用修改。

void GaugeRedraw(
   GAUGE_STR &g       // 引用表盘结构
); 

参数

& g

&[输入]引用表结构。

3.10。量表新值

更新销定位和显示值。

void GaugeNewValue(
   GAUGE_STR &g,     // 引用表盘结构
   double v          // 变化值
);

参数

& g

&[输入]引用表结构。

五伏特

&[输入]当前更改值。

3.11。仪表删除

删除复合拨号的图形对象。从OndeInit()处理器调用函数。

void GaugeDelete(
   GAUGE_STR &g      // 引用表盘结构
);

参数

& g

&[输入]引用表结构。

3.12。仪表计算位置

计算拨号对象的坐标。如果禁用相对定位,它将始终返回一些坐标。如果参考对象的位置或大小发生了更改,则坐标可能会有所不同。

bool GaugeCalcLocation( 
   GAUGE_STR& g         // 引用表盘结构
);

参数

& g

&[输入]引用表结构。

返回值

&如果坐标与前面的值不同,则返回true。否则,返回false。如果函数返回true,将调用GaugeRocation()函数来应用计算的参数。

3.13。计重定位

将复合表盘的图形对象定位在图表上的指定点。如果设置了相对定位,并且GaugeCalcLocation()函数返回true,则需要调用它。

void GaugeRelocation(
   GAUGE_STR &g       // 引用表盘结构
);

参数

& g

&[输入]引用表结构。

4。枚举

表2列出了可用作函数参数的枚举。

枚举 说明
枚举大小写边框样式 边框样式
枚举大小写样式 实体样式
Enum_Gauge_图例 图形样式
枚举标记样式 比例样式
Enum_Mul_秤 比例标签乘数
枚举中心样式 手写笔
的中央样式
枚举指针填充 表针填充面积法
枚举中继模式 相对定位方法
枚举缩放样式 比例样式
枚举大小 尺寸

表2。枚举列表

4.1。枚举大小写边框样式

边框样式值列在表3中。

标识符 说明
案例编号: 无边界
大小写边框 细线
箱边框厚 粗边

表3。枚举大小写边框样式的值

4.2。枚举CaseSype风格

实体风格。表4列出了这些值。

标识符 说明
案例号 循环实体
案例号 行业实体

表4。枚举大小写样式
的值

4.3。枚举仪表图例

图形类型。表5列出了这些值。

标识符 &说明
图例说明 硬读说明
传奇单元 测量单元
莱文特穆尔 比例标签乘数
传奇价值 电流变化值

表5。Enum_Gauge_Legend
的值

4.4。枚举标记样式

规模风格。表6列出了这些值。

标识符 &说明
马尔克斯内 标签内侧对齐
马尔克斯中部 标记中心布置
马尔克斯外 标签横向对齐

表6。枚举标记样式
的值

4.5。枚举多尺度

刻度标签倍数。表7列出了这些值。

&标识符 意义 显示
穆勒万 10000 10K
穆尔1000 1000 1K
Mul100100 100 100;
木素10 10 10;
多瘤1号 1 &不显示
穆勒01 0.1 和/ 10
Muly00 0.01 和/ 100
Muly10001 0.001 n/s/1k
Mull 0 0 0 1 0.0001 /10K

表7。Enum_Mul_秤
的值

4.6。枚举中心样式

触笔的中心样式。表8列出了这些值。

标识符 说明
NdCS-NO No needle center
NDCS-小 显示较小的
NDCS-大 显示较大的

表8。枚举中心样式
的值

4.7。枚举指针填充

用针填充区域的方法。表9列出了这些值。

&标识符 &说明
针刺充填 无边缘消除混叠填充针
针叶树 边缘消除混叠填充针
针阀 不要填充针,但使用边缘消除混叠

表9。枚举指针填充值

4.8。枚举中继模式

相对定位法。表10列出了这些值。

&标识符 &说明
相对模式 禁止相对定位
相对模式
相对模式垂直 立式
相对模式诊断 对角线

表10。枚举关联模式
的值

4.9。枚举缩放样式

规模风格。数值如表11所示。

标识符 &说明
鳞片内 校准标签是校准内的
鳞片外 磅秤标签位于磅秤外部。

表11。枚举缩放样式
的值

4.10。枚举大小

尺寸。表12列出了这些值。

标识符 &说明
小尺寸 更小的
大小中间 培养基
大尺寸的 大型

表12。枚举大小
的值

5。宏替换

尺寸系数:

#define DIAM_TO_NDCSL_RATIO   5   //表针中心直径 (较小) 作为实体直径的百分比
#define DIAM_TO_NDCSB_RATIO   7.5 //表针中心直径 (较大) 作为实体直径的百分比

//---
#define DIAM_TO_BD_SIZE_S     2 //边框宽度 (较小) 作为实体直径的百分比

#define DIAM_TO_BD_SIZE_B     5 //边框宽度 (较大) 作为实体直径的百分比
//---
#define DIAM_TO_BD_GAP_S      2.0 //自表盘实体边框到内部元素(较小) 的空间作为实体直径的百分比
#define DIAM_TO_BD_GAP_M      3.0 //自表盘实体边框到内部元素(中等) 的空间作为实体直径的百分比
#define DIAM_TO_BD_GAP_L      7.0 //自表盘实体边框到内部元素(较大) 的空间作为实体直径的百分比
//---
#define DIAM_TO_MSZ_MJ_S      3.3 //主要刻度 (较小) 的大小作为实体直径的百分比
#define DIAM_TO_MSZ_MD_S      2.3 //中等刻度 (较小) 的大小作为实体直径的百分比
#define DIAM_TO_MSZ_MN_S      1.3 //次要刻度 (较小) 的大小作为实体直径的百分比
//---
#define DIAM_TO_MSZ_MJ_M      6.5 //主要刻度 (中等) 的大小作为实体直径的百分比
#define DIAM_TO_MSZ_MD_M      4.8 //中等刻度 (中等) 的大小作为实体直径的百分比
#define DIAM_TO_MSZ_MN_M      3.0 //次要刻度 (中等) 的大小作为实体直径的百分比
//---
#define DIAM_TO_MSZ_MJ_L      10.0 //主要刻度 (较大) 的大小作为实体直径的百分比
#define DIAM_TO_MSZ_MD_L      7.5  //中等刻度 (较大) 的大小作为实体直径的百分比
#define DIAM_TO_MSZ_MN_L      5.0  //次要刻度 (较大) 的大小作为实体直径的百分比
//---
#define DIAM_TO_MFONT_SZ_S    4   //刻度标签 (较小) 的字号作为实体直径的百分比
#define DIAM_TO_MFONT_SZ_M    6.5 //刻度标签 (中等) 的字号作为实体直径的百分比
#define DIAM_TO_MFONT_SZ_L    10  //刻度标签 (较大) 的字号作为实体直径的百分比

默认颜色:

#define DEF_COL_SCALE      clrBlack
#define DEF_COL_MARK_FONT  clrBlack
#define DEF_COL_CASE       clrMintCream
#define DEF_COL_BORDER     clrLightSteelBlue
#define DEF_COL_LAB        clrDarkGray
#define DEF_COL_NCENTER    clrLightSteelBlue
#define DEF_COL_NEEDLE     clrDimGray

6。修改ccanvas类

A 6033 6.1。使用消除混叠算法绘制段落

方法Linea允许使用抗混叠算法绘制段落。但当我们画圆形的刻度线时,就会出现一个问题。当我们将段落的起始和结束坐标从极坐标系转换为笛卡尔坐标系时,我们将分数四舍五入为整数。因此标记看起来有点倾斜,如图例所示。11(b)。

这就是我们添加Linea2方法的原因,它实际上与Linea不同,它将输入参数x1、y1、x2、y2更改为双精度。所以我们可以转换分数坐标来消除这个问题,这可以在图例11(c)中看到。

//+------------------------------------------------------------------+
//| 利用抗锯齿画线 (带样式) v.2                                          |
//+------------------------------------------------------------------+
void CCanvas::LineAA2(const double x1,const double y1,const double x2,const double y2,const uint clr,const uint style)
  {
//--- 线超过图像边界
   if((x1<0 && x2<0) || (y1<0 && y2<0))
      return;
   if(x1>=m_width && x2>=m_width)
      return;
   if(y1>=m_height && y2>=m_height)
      return;
//--- 检查
   if(x1==x2 && y1==y2)
     {
      PixelSet(int(x1),int(y1),clr);
      return;
     }
//--- 设置线样式
   if(style!=UINT_MAX)
      LineStyleSet(style);
//--- 初步计算
   double dx=x2-x1;
   double dy=y2-y1;
   double xy=sqrt(dx*dx+dy*dy);
   double xx=x1;
   double yy=y1;
   uint   mask=1<<m_style_idx;
//--- 设置像素
   dx/=xy;
   dy/=xy;
   do
     {
      if((m_style&mask)==mask)
         PixelSetAA(xx,yy,clr);
      xx+=dx;
      yy+=dy;
      mask<<=1;
      if(mask==0x1000000)
         mask=1;
     }
   while(fabs(x2-xx)>=fabs(dx) && fabs(y2-yy)>=fabs(dy));
  } 

传说。11描述了绘制比例尺标记的各种方法的示例:

  • 方法线(a)
  • 直线法(b)
  • 方法linea2(c)

刻度表盘1

传说。11。各种比例标记绘制方法(200%)

6.2。用边缘消除混叠填充区域

方法填充是指在不使用消除混叠算法的情况下填充有界区域。如果我们使用线性方法来填充一个有界区域,则区域填充是不完整的,如图12(a)所示。

刻度表盘2

传说。12。使用边缘消除混叠填充区域(最多200%)

所以我们添加Fill2方法。区别在于它不填充背景色,而是填充任何不同于边界区域的颜色。它允许填充浅色,而填充方法无法做到这一点。插图。12(b)描述了一个例子。

//+------------------------------------------------------------------+
//| 以颜色填充闭合区域 (v.2)                                            |
//+------------------------------------------------------------------+
void CCanvas::Fill2(int x,int y,const uint clr)
  {
//--- 检查
   if(x<0 || x>=m_width || y<0 || y>=m_height)
      return;
//---
   int  index=y*m_width+x;
   uint old_clr=m_pixels[index];
//--- 检查替换是否必要
   if(old_clr==clr)
      return;
//--- 使用哑元栈来模拟深度嵌套的递归调用
   int  stack[];
   uint count=1;
   int  idx;
   int  total=ArraySize(m_pixels);
//--- 为堆栈分配内存
   if(ArrayResize(stack,total)==-1)
      return;
   stack[0]=index;
   m_pixels[index]=clr;
   for(uint i=0;i<count;i++)
     {
      index=stack[i];
      x=index%m_width;
      //--- 左邻点
      idx=index-1;
      if(x>0 && m_pixels[idx]!=clr)
        {
         stack[count]=idx;
         if(m_pixels[idx]==old_clr)
            count++;
         m_pixels[idx]=clr;
        }
      //--- 顶邻点
      idx=index-m_width;
      if(idx>=0 && m_pixels[idx]!=clr)
        {
         stack[count]=idx;
         if(m_pixels[idx]==old_clr)
            count++;
         m_pixels[idx]=clr;
        }
      //--- 右邻点
      idx=index+1;
      if(x<m_width-1 && m_pixels[idx]!=clr)
        {
         stack[count]=idx;
         if(m_pixels[idx]==old_clr)
            count++;
         m_pixels[idx]=clr;
        }
      //--- 底邻点
      idx=index+m_width;
      if(idx<total && m_pixels[idx]!=clr)
        {
         stack[count]=idx;
         if(m_pixels[idx]==old_clr)
            count++;
         m_pixels[idx]=clr;
        }
     }
//--- 释放内存
   ArrayFree(stack);
  }  

然而,这种方法有其缺点。如图12(c)所示,如果有一个小的锐角,它的一部分将不会被填充。所以我们找到了解决这个问题的方法。

&首先,整个画布(针层)填充针颜色:

n.canvas.Fill(10, 10, ColorToARGB(n.needle.c, n.transparency));

&然后,我们使用Linea2方法绘制三段合成的台针:

n.canvas.LineAA2(db_xbuf[0], db_ybuf[0], db_xbuf[1], db_ybuf[1], 0);
n.canvas.LineAA2(db_xbuf[1], db_ybuf[1], db_xbuf[2], db_ybuf[2], 0);
n.canvas.LineAA2(db_xbuf[2], db_ybuf[2], db_xbuf[0], db_ybuf[0], 0);

&之后,我们使用Fill2方法将触笔周围的区域填充为透明色:

n.canvas.Fill2(10, 10, 0);

这不是最好的方法,但它可以拔出正确的针。

刻度表盘3

传说。13。用不同的方法填充针

传说。13以不同的方式描述打捆针。

  • (a)用Linea2法画出三段合成针,并用Fill2法填充。
  • b)用倒三角形法抽针。
  • c)用线性方法画三段合成未填充触针。

如我们所见,指针如图例所示。13(b)变形,并以90度角轻微偏离。此外,我们还可以看到,当我们从极坐标转换为直角坐标时,由于坐标值的舍入,销会从中心移动。但同时,这种方法通常在资源密集的情况下实现(稍后我们将返回到这一点)。图13(c)所示的触笔是两种方法之间的折衷。它使用Linea2方法绘制合成针的三个部分,但不填充该区域。

7。应用程序

让我们通过几个例程来检查库的应用程序。

7.1。当前利润指标

我们从最简单的开始。下面的例程演示向EA或指示器添加拨号的基本设置。

//+------------------------------------------------------------------+
//|                                       profit_gauge_indicator.mq5 |
//|                                         Copyright 2015, Decanium |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Decanium"
#property version   "1.00"
#property indicator_plots 0
#property indicator_chart_window

#include <Gauge/gauge_graph.mqh>

input string inp_gauge_name="gg01";                  // 指标名
input int inp_x = 40;                                // 水平偏移
input int inp_y = 40;                                // 垂直偏移
input int inp_size=300;                              // 指标大小
input string inp_ObjRel="";                          // 相对定位情况下的基准指标名
input ENUM_REL_MODE inp_rel_mode=RELATIVE_MODE_NONE; // 相对定位模式
input ENUM_BASE_CORNER inp_corner=CORNER_LEFT_UPPER; // 锚点边角
input bool inp_back=false;                           // 指标作为背景
input uchar inp_scale_transparency=0;                // 刻度透明级别, 0..255
input uchar inp_needle_transparency=0;               // 表针透明级别, 0..255

//--- 声明表盘结构
GAUGE_STR g0;
//+------------------------------------------------------------------+
//| 自定义指标初始化函数                                                | 
//+------------------------------------------------------------------+
int OnInit()
  {
//--- 创建表盘
   if(GaugeCreate(inp_gauge_name,g0,inp_x,inp_y,inp_size,inp_ObjRel,inp_rel_mode,
      inp_corner,inp_back,inp_scale_transparency,inp_needle_transparency)==false)
      return(INIT_FAILED);
//--- 绘制表盘
   GaugeRedraw(g0);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 自定义指标逆始函数                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- 删除表盘
   GaugeDelete(g0);
   ChartRedraw();
  }    
//+------------------------------------------------------------------+
//| 自定义指标迭代函数                                                  |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//--- 更新读数
   double profit=AccountInfoDouble(ACCOUNT_PROFIT);
   GaugeNewValue(g0,profit);
//---
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent 函数                                                   |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   if(id==CHARTEVENT_CHART_CHANGE)
     {
      if(GaugeCalcLocation(g0)==true)
         GaugeRelocation(g0);
     }
  }
//+------------------------------------------------------------------+

首先,我们需要声明拨号结构。然后,我们继续初始化使用GaugeCreate()函数创建的刻度盘,并调用绘图函数-GaugerDraw()。GaugenewValue()可用于更新读数。在这种情况下,它由oncalculate()处理器调用。

刻度盘如图1.14所示。

刻度表盘4

传说。14。拨号盘
的默认外观

现在我们将添加设置刻度范围和旋转角度的功能。它将向输入列表添加两个参数。

input int inp_scale_range=270;   // 刻度范围, 30..320 度
input int inp_rotation=45;       // 刻度旋转, 0..359 度

现在,我们扩展来初始化代码,并使用函数调用来设置比例参数。

//--- 设置刻度和标记的参数
   GaugeSetScaleParameters(g0,inp_scale_range,inp_rotation,-200,400,MUL_1,SCALE_INNER,clrBlack);

为了补充新的输入参数,我们还将设置:

  • 新的最大值和最小值(分别为-200和400)
  • 比例标签乘数(mul_1)
  • 比例样式(内部比例标签)
  • 标签颜色(CLRBLACK)

由于我们改变了尺度极值,因此需要调整主标志的步长。最好的值是100,因为它消除了多余的文本。在这里,我们将在两个主要标记之间放置一个中等标记,在两个中等标记之间放置四个次要标记。所以在标签之间,我们的最小步长等于10。

   GaugeSetMarkParameters(g0,MARKS_INNER,SIZE_MIDDLE,100,1,4);

现在,我们将突出显示两个数据范围。范围有索引0,从200开始,到400结束,用颜色clrlimegreen突出显示。范围有索引1,从-100开始,到-200结束,用颜色clrcoal突出显示。

//--- 刻度的强调范围
   GaugeSetRangeParameters(g0,0,true,200,400,clrLimeGreen);
   GaugeSetRangeParameters(g0,1,true,-100,-200,clrCoral);

现在,让我们继续设置插图。我们确认刻度盘的描述、测量单位和电流值应切至一个小数点。让我们逐一回顾一下。

表说明:

   GaugeSetLegendParameters(g0,LEGEND_DESCRIPTION,true,"Profit",3,0,14,"Arial",false,false);

显示字符串为“利润”,半径为3,角度为0,字体编号为14个条件单位。

计量单位:

   GaugeSetLegendParameters(g0,LEGEND_UNITS,true,"USD",8,215,10,"Arial",true,false);

显示字符串为“美元”,半径为8,角度为215,字体编号为10个条件单位。

当前值:

   GaugeSetLegendParameters(g0,LEGEND_VALUE,true,"1",4,225,20,"Arial",true,false);

这里,字符串“1”表示显示格式(小数点后一个小数点)。坐标:半径4,角度255。The number is 20 conditional units.

因此,在我们执行了一些附加设置之后,这个拨号盘将如图1.15所示。

刻度表盘5

传说。15。添加其他设置后拨号
的外观

7.2。刻度盘指示器

现在让我们来看一个更复杂的例子,一个称为仪表板的指示器。如图1所示。该指标显示当前收益、点差、可用保证金百分比和当前ATR、强度指数和RSI值。

首先,我们需要声明拨号结构数组。nbsp;

//--- 声明表盘结构数组
GAUGE_STR gg[6];

然后我们需要创建和调整拨号。

页边距水平指示器将放置在左下角。它有绝对坐标,所有其他指示器都将放置在它旁边。

//--- 构建 gg00 表盘, 保证金级别
   if(GaugeCreate("gg00",gg[0],5,-90,240,"",RELATIVE_MODE_NONE,
      CORNER_LEFT_LOWER,inp_back,inp_scale_transparency,inp_needle_transparency)==false)
      return(INIT_FAILED);
//--- 设置实体参数
   GaugeSetCaseParameters(gg[0],CASE_SECTOR,DEF_COL_CASE,CASE_BORDER_THIN,DEF_COL_BORDER,SIZE_MIDDLE);
//--- 设置刻度和标记的参数
   GaugeSetScaleParameters(gg[0],120,35,800,2000,MUL_100,SCALE_INNER,clrBlack);
   GaugeSetMarkParameters(gg[0],MARKS_INNER,SIZE_MIDDLE,200,1,4);
   GaugeSetMarkLabelFont(gg[0],SIZE_MIDDLE,"Arial",false,false,DEF_COL_MARK_FONT);
//--- 刻度的强调范围
   GaugeSetRangeParameters(gg[0],0,true,1400,2000,clrLimeGreen);
   GaugeSetRangeParameters(gg[0],1,true,1000,800,clrCoral);
//--- 设置文字标签
   GaugeSetLegendParameters(gg[0],LEGEND_DESCRIPTION,true,"Margin lvl",4,15,12,"Arial",false,false);
   GaugeSetLegendParameters(gg[0],LEGEND_VALUE,true,"0",3,80,16,"Arial",true,false);
   GaugeSetLegendParameters(gg[0],LEGEND_MUL,true,"",4,55,8,"Arial",true,false);
//--- 设置表针参数
   GaugeSetNeedleParameters(gg[0],NDCS_SMALL,DEF_COL_NCENTER,DEF_COL_NEEDLE,NEEDLE_FILL_AA);

我们将继续安排底线。接下来是当前的利润指标。

//--- 构建 gg01 表盘, 当前盈利
   if(GaugeCreate("gg01",gg[1],-80,20,320,"gg00",RELATIVE_MODE_HOR,
      CORNER_LEFT_LOWER,inp_back,inp_scale_transparency,inp_needle_transparency)==false)
      return(INIT_FAILED);
//--- 设置实体参数
   GaugeSetCaseParameters(gg[1],CASE_SECTOR,DEF_COL_CASE,CASE_BORDER_THIN,DEF_COL_BORDER,SIZE_MIDDLE);
//--- 设置刻度和标记的参数
   GaugeSetScaleParameters(gg[1],200,0,-400,400,MUL_1,SCALE_INNER,clrBlack);
   GaugeSetMarkParameters(gg[1],MARKS_INNER,SIZE_MIDDLE,100,1,4);
   GaugeSetMarkLabelFont(gg[1],SIZE_MIDDLE,"Arial",false,false,DEF_COL_MARK_FONT);
//--- 刻度的强调范围
   GaugeSetRangeParameters(gg[1],0,true,200,400,clrLimeGreen);
   GaugeSetRangeParameters(gg[1],1,true,-200,-400,clrCoral);
//--- 设置文字标签
   GaugeSetLegendParameters(gg[1],LEGEND_DESCRIPTION,true,"Profit",3,0,16,"Arial",false,false);
   GaugeSetLegendParameters(gg[1],LEGEND_UNITS,true,"USD",3,-90,10,"Arial",true,false);
   GaugeSetLegendParameters(gg[1],LEGEND_VALUE,true,"1",3,90,12,"Arial",true,false);
//--- 设置表针参数
   GaugeSetNeedleParameters(gg[1],NDCS_SMALL,DEF_COL_NCENTER,DEF_COL_NEEDLE,NEEDLE_FILL_AA);

差分指示器接近底线。

//--- 构建 gg02 表盘, 点差
   if(GaugeCreate("gg02",gg[2],-80,-20,240,"gg01",RELATIVE_MODE_HOR,
      CORNER_LEFT_LOWER,inp_back,inp_scale_transparency,inp_needle_transparency)==false)
      return(INIT_FAILED);
//--- 设置实体参数
   GaugeSetCaseParameters(gg[2],CASE_SECTOR,DEF_COL_CASE,CASE_BORDER_THIN,DEF_COL_BORDER,SIZE_MIDDLE);
//--- 设置刻度和标记的参数
   GaugeSetScaleParameters(gg[2],120,-35,60,0,MUL_1,SCALE_INNER,clrBlack);
   GaugeSetMarkParameters(gg[2],MARKS_INNER,SIZE_MIDDLE,10,1,4);
   GaugeSetMarkLabelFont(gg[2],SIZE_MIDDLE,"Arial",false,false,DEF_COL_MARK_FONT);
//--- 刻度的强调范围
   GaugeSetRangeParameters(gg[2],0,true,35,10,clrLimeGreen);
   GaugeSetRangeParameters(gg[2],1,true,50,60,clrCoral);
//--- 设置文字标签
   GaugeSetLegendParameters(gg[2],LEGEND_DESCRIPTION,true,"Spread",4,-15,14,"Arial",false,false);
   GaugeSetLegendParameters(gg[2],LEGEND_VALUE,true,"0",3,-80,16,"Arial",true,false);
//--- 设置表针参数
   GaugeSetNeedleParameters(gg[2],NDCS_SMALL,DEF_COL_NCENTER,DEF_COL_NEEDLE,NEEDLE_FILL_AA);

指示器ATR(左上角)相对于边距指示器放置。

//--- 构建 gg03 表盘, ATR
   if(GaugeCreate("gg03",gg[3],30,0,180,"gg00",RELATIVE_MODE_VERT,
      CORNER_LEFT_LOWER,inp_back,inp_scale_transparency,inp_needle_transparency)==false)
      return(INIT_FAILED);
//--- 设置实体参数
   GaugeSetCaseParameters(gg[3],CASE_ROUND,DEF_COL_CASE,CASE_BORDER_THIN,DEF_COL_BORDER,SIZE_MIDDLE);
//--- 设置刻度和标记的参数
   GaugeSetScaleParameters(gg[3],270,45,0.001,0.004,MUL_00001,SCALE_INNER,clrBlack);
   GaugeSetMarkParameters(gg[3],MARKS_INNER,SIZE_LARGE,0.001,9,3);
   GaugeSetMarkLabelFont(gg[3],SIZE_LARGE,"Arial",false,false,DEF_COL_MARK_FONT);
//--- 刻度的强调范围
   GaugeSetRangeParameters(gg[3],0,true,0.002,0.001,clrYellow);
//--- 设置文字标签
   GaugeSetLegendParameters(gg[3],LEGEND_DESCRIPTION,true,"ATR",7,-140,26,"Arial",false,false);
//GaugeSetLegendParameters(gg[3],LEGEND_UNITS,true,"USD",8,180,5,"Arial",true,false);
   GaugeSetLegendParameters(gg[3],LEGEND_VALUE,true,"5",2,180,14,"Arial",true,false);
   GaugeSetLegendParameters(gg[3],LEGEND_MUL,true,"",2,0,20,"Arial",true,false);
//--- 设置表针参数
   GaugeSetNeedleParameters(gg[3],NDCS_SMALL,DEF_COL_NCENTER,DEF_COL_NEEDLE,NEEDLE_FILL_AA);

指示器RSI位于(上方)相对于点差指示器的位置。

//--- 构建 gg04 表盘, RSI
   if(GaugeCreate("gg04",gg[4],-30,0,180,"gg02",RELATIVE_MODE_VERT,
      CORNER_LEFT_LOWER,inp_back,inp_scale_transparency,inp_needle_transparency)==false)
      return(INIT_FAILED);
//--- 设置实体参数
   GaugeSetCaseParameters(gg[4],CASE_ROUND,DEF_COL_CASE,CASE_BORDER_THIN,DEF_COL_BORDER,SIZE_MIDDLE);
//--- 设置刻度和标记的参数
   GaugeSetScaleParameters(gg[4],270,45,0,100,MUL_10,SCALE_INNER,clrBlack);
   GaugeSetMarkParameters(gg[4],MARKS_INNER,SIZE_LARGE,10,1,4);
   GaugeSetMarkLabelFont(gg[4],SIZE_LARGE,"Arial",false,false,DEF_COL_MARK_FONT);
//--- 设置文字标签
   GaugeSetLegendParameters(gg[4],LEGEND_DESCRIPTION,true,"RSI",7,-140,26,"Arial",false,false);
   GaugeSetLegendParameters(gg[4],LEGEND_VALUE,true,"2",2,180,16,"Arial",true,false);
   GaugeSetLegendParameters(gg[4],LEGEND_MUL,true,"",2,0,20,"Arial",true,false);
//--- 设置表针参数
   GaugeSetNeedleParameters(gg[4],NDCS_SMALL,DEF_COL_NCENTER,DEF_COL_NEEDLE,NEEDLE_FILL_AA);

指标强度指数高于当前利润指标。

//--- 构建 gg05 表盘, 力度
   if(GaugeCreate("gg05",gg[5],-10,60,180,"gg03",RELATIVE_MODE_HOR,
      CORNER_LEFT_LOWER,inp_back,inp_scale_transparency,inp_needle_transparency)==false)
      return(INIT_FAILED);
//--- 设置实体参数
   GaugeSetCaseParameters(gg[5],CASE_ROUND,DEF_COL_CASE,CASE_BORDER_THIN,DEF_COL_BORDER,SIZE_MIDDLE);
//--- 设置刻度和标记的参数
   GaugeSetScaleParameters(gg[5],270,45,-4,4,MUL_1,SCALE_INNER,clrBlack);
   GaugeSetMarkParameters(gg[5],MARKS_INNER,SIZE_LARGE,1,1,4);
   GaugeSetMarkLabelFont(gg[5],SIZE_LARGE,"Arial",false,false,DEF_COL_MARK_FONT);
//--- 刻度的强调范围
   GaugeSetRangeParameters(gg[5],0,true,-1,-4,clrMediumSeaGreen);
   GaugeSetRangeParameters(gg[5],1,true,1,4,clrCrimson);
//--- 设置文字标签
   GaugeSetLegendParameters(gg[5],LEGEND_DESCRIPTION,true,"Force",7,-140,20,"Arial",false,false);
   GaugeSetLegendParameters(gg[5],LEGEND_VALUE,true,"5",2,180,14,"Arial",true,false);
   GaugeSetLegendParameters(gg[5],LEGEND_MUL,true,"",3,0,10,"Arial",true,false);
//--- 设置表针参数
   GaugeSetNeedleParameters(gg[5],NDCS_SMALL,DEF_COL_NCENTER,DEF_COL_NEEDLE,NEEDLE_FILL_AA);

刻度盘是圆形的。

//--- 绘制表盘
   for(int i=0; i<6;i++)
     {
      GaugeRedraw(gg[i]);
      GaugeNewValue(gg[i],0);
     }

当onCalculate()事件发生时,我们重新计算当前值,并为每个指标调用GaugenewValue()函数。

//--- 更新读数
//--- 点差
   GaugeNewValue(gg[2],spread[rates_total-1]);
//--- 当前盈利   
   double profit=AccountInfoDouble(ACCOUNT_PROFIT);
   GaugeNewValue(gg[1],profit);
//--- 保证金级别
   double margin_level=AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);
   GaugeNewValue(gg[0],margin_level);
//--- 指示器 ATR
   calculated=BarsCalculated(handle_ATR);
   if(calculated>0)
     {
      double ival[1];
      if(CopyBuffer(handle_ATR,0,0,1,ival)<0)
         Print("ATR CopyBuffer 错误");
      else
         GaugeNewValue(gg[3],ival[0]);
     }
//--- 指示器 RSI
   calculated=BarsCalculated(handle_RSI);
   if(calculated>0)
     {
      double ival[1];
      if(CopyBuffer(handle_RSI,0,0,1,ival)<0)
         Print("RSI CopyBuffer 错误");
      else
         GaugeNewValue(gg[4],ival[0]);
     }
//--- 指示器力度指数
   calculated=BarsCalculated(handle_Force);
   if(calculated>0)
     {
      double ival[1];
      if(CopyBuffer(handle_Force,0,0,1,ival)<0)
         Print("力度指数 CopyBuffer 错误");
      else
         GaugeNewValue(gg[5],ival[0]);
     }

请注意,在给定的例程中,GaugeRocation()不是从OnChartEvent()事件调用的。虽然这里使用了相对定位,但是如果它们的位置或大小发生了变化,我们不需要重新计算刻度盘的坐标,因为所有刻度盘都将初始化一次。

8。资源强度评估

每当更新读数时,针层将完全重新绘制。它可能经常发生,即使在某些情况下,一秒钟几次。这就是绘图笔资源强度问题比较严重的原因。我们将编写一个小脚本来评估使用各种区域填充方法绘制表时的CPU开销。

//+------------------------------------------------------------------+
//|                                                    test_fill.mq5 |
//|                                         Copyright 2015, Decanium |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Decanium"
#property version   "1.00"

#include <Canvas/Canvas2.mqh>

CCanvas canvas;
//+------------------------------------------------------------------+
//| 脚本程序开始函数                                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   Print("***** 开始测试 *****");
//---
   string ObjName="test";
   ObjectDelete(0,ObjName);
   canvas.CreateBitmapLabel(ObjName,10,10,400,400,COLOR_FORMAT_ARGB_NORMALIZE);
//---
   int x[3]={200,185,215};
   int y[3]={70, 250,250};
   int cycles=1000;
   uint col=ColorToARGB(clrRed,255);
   uint c1,c2;
//--- 测试采用边缘抗锯齿填充区域
   canvas.Erase();
   c1=GetTickCount();
   for(int i=0; i<cycles; i++)
     {
      canvas.Fill(10, 10, col);
      canvas.LineAA2(x[0], y[0], x[1], y[1], 0);
      canvas.LineAA2(x[1], y[1], x[2], y[2], 0);
      canvas.LineAA2(x[2], y[2], x[0], y[0], 0);
      canvas.Fill2(10, 10, 0);
     }
   c2=GetTickCount();
   canvas.Update(true);
   Print("填充 AA: ",c2-c1," 毫秒, ",cycles," 循环, ",
         DoubleToString(double(c2-c1)/double(cycles),2)," 每循环毫秒");
//--- 测试抗锯齿等高线但不填充
   canvas.Erase();
   c1=GetTickCount();
   for(int i=0; i<cycles; i++)
     {
      canvas.LineAA2(x[0], y[0], x[1], y[1], col);
      canvas.LineAA2(x[1], y[1], x[2], y[2], col);
      canvas.LineAA2(x[2], y[2], x[0], y[0], col);
     }
   c2=GetTickCount();
   canvas.Update(true);
   Print("不填充 AA: ",c2-c1," 毫秒, ",cycles," 循环, ",
         DoubleToString(double(c2-c1)/double(cycles),2)," 每循环毫秒");
//--- 测试不使用抗锯齿填充区域
   canvas.Erase();
   c1=GetTickCount();
   for(int i=0; i<cycles; i++)
     {
      canvas.FillTriangle(x[0],y[0],x[1],y[1],x[2],y[2],col);
      canvas.LineAA2(x[0], y[0], (x[1]+x[2])/2, y[1], col);
     }
   c2=GetTickCount();
   canvas.Update(true);
   Print("填充: ",c2-c1," 毫秒, ",cycles," 循环, ",
         DoubleToString(double(c2-c1)/double(cycles),2)," 每循环毫秒");
  }
//+------------------------------------------------------------------+

该脚本在一个循环中为每种绘制指针的方法启动1000次,并测量过程中花费的毫秒数。

刻度表盘6

传说。16。资源强度试验结果

如结果所示,使用消除混叠边绘制填充针比不使用消除混叠填充针长数百倍,比使用消除混叠绘制无填充轮廓长数十倍。在这种情况下,美真的有它的价值。

结论

在本文中,我们回顾了一组绘图拨号功能。创建库的主要目标是简化将刻度盘添加到EA或度量的工作,而不知道绘图和几何图形的细节。不过,由你来决定我们是否达到了这个目标。

应特别注意资源的强度。在oncalculate()处理器中耗时的计算会导致终端崩溃。因此,我们建议一种折衷的方法来绘制针(无填充的消除混叠)。

本文由MetaQuotes Software Corp.翻译自俄语原文
,网址为https://www.mql5.com/ru/articles/1699。

附加文件下载zip dashboard.mq5(22.69 kb)canvas 2.mqh(171.52 kb)profit_gauge_indicator.mq5(8.15 kb)gauge_graph.mqh(154.69 kb)

 

 


MyFxtop迈投(www.myfxtop.com)-靠谱的外汇跟单社区,免费跟随高手做交易!

 

免责声明:本文系转载自网络,如有侵犯,请联系我们立即删除,另:本文仅代表作者个人观点,与迈投财经(www.myfxtop.cn)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。

本文来自网络,不代表迈投财经立场,转载请注明出处:https://www.myfxtop.cn/ea/5943.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: myfxtop@hotmail.com

9:30 - 18:00/Mon-Fri
返回顶部