测试CGraphic--问题和建议 - 页 6 12345678910111213 新评论 --- 2017.01.31 15:19 #51 Roman Konopelko: 在CGraphic类中,我按照你的要求,在所有地方都用uint替换了颜色类型。 此外,我还为CCanvas类添加了新的方法,它允许以指定的厚度绘制基元。 为了与CCanvas的创新保持一致,我扩展了CCurve的属性。 当用线条绘制曲线时,你现在可以指定线条的粗细和其末端的样式。 这真是太棒了。 Roman Konopelko 2017.02.08 16:56 #52 对花键的处理(用贝塞尔曲线进行插值)进行了修改。它的实现已经从CGraphics类中直接移到了CCanvas中,这样就可以在图形库之外构建花样。 此外,还增加了渲染闭合花键的算法。因此,CCanvas类 现在有两个新的公共方法。void PolylineSmooth(const int &x[],const int &y[],const uint clr,const int size, ENUM_LINE_STYLE style=STYLE_SOLID,ENUM_LINE_END end_style=LINE_END_ROUND, double tension=0.5,double step=10); void PolygoneSmooth(int &x[],int &y[],const uint clr,const int size, ENUM_LINE_STYLE style=STYLE_SOLID,ENUM_LINE_END end_style=LINE_END_ROUND, double tension=0.5,double step=10);这些方法允许以给定的样式和给定的厚度来绘制花键。 由于贝塞尔曲线相当精确地描述了圆和椭圆,因此没有明显的必要用新的方法来增强CCanvas类,以渲染具有给定厚度的这些基元。 基于PolygoneSmooth方法的贝塞尔曲线对椭圆进行逼近的例子。#include <Canvas\Canvas.mqh> //+------------------------------------------------------------------+ //| Get arrays with ellipse coordinates | //+------------------------------------------------------------------+ void Ellipse(int &x[],int &y[]) { int xc = 750; int yc = 300; int rx = 300; int ry = 150; ArrayResize(x,16); ArrayResize(y,16); int i=0; for(double fi=0; fi<2*M_PI; fi+=M_PI_4/2,i++) { x[i]=(int)MathRound(xc+cos(fi)*rx); y[i]=(int)MathRound(yc+sin(fi)*ry); } } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { CCanvas canvas; canvas.CreateBitmapLabel(0,0,"Canvas",0,0,1500,600); canvas.Erase(ColorToARGB(clrWhite)); int x[]; int y[]; Ellipse(x,y); canvas.PolygoneSmooth(x,y,ColorToARGB(clrBlack),20,STYLE_SOLID,LINE_END_BUTT,0.5,1); canvas.Arc(750,300,300,150,0,M_PI*2,ColorToARGB(clrRed)); canvas.Update(); }结果。 Roman Konopelko 2017.02.08 16:59 #53 实现图形库多功能性的另一个可能步骤:自定义曲线绘制模式CURVE_CUSTOM。这种模式将消除继承CGraphic类和重载...Plot方法的需要,以便以不同于库的标准工具的方式绘制曲线。为了实现这种模式CURVE_CUSTOM,新的属性将被添加到CCurve类。 //--- gets or sets the custom properties PlotFucntion CustomPlotFunction(void) const { return(m_custom_plot_func); } void *CustomPlotCBData(void) const { return(m_custom_plot_cbdata); } void CustomPlotFunction(PlotFucntion func) { m_custom_plot_func=func; } void CustomPlotCBData(void *cbdata) { m_custom_plot_cbdata=cbdata; }它是基于一个新的指向PlotFucntion函数的指针。typedef void(*PlotFucntion)(double &x[],double &y[], int size, CGraphic *graphic,CCanvas *canvas,void *cbdata);这种方法为绘制地块提供了新的可能性。让我们以CGraphics库为例来实现蜡烛图的绘制。1.让我们创建一个容器类,其中将存储单个蜡烛的所有数据。//+------------------------------------------------------------------+ //| Class CCandle | //| Usage: class to represent the candle | //+------------------------------------------------------------------+ class CCandle: public CObject { private: double m_open; double m_close; double m_high; double m_low; uint m_clr_inc; uint m_clr_dec; int m_width; public: CCandle(const double open,const double close,const double high,const double low, const int width,const uint clr_inc=0x000000,const uint clr_dec=0xF5F5F5); ~CCandle(void); double OpenValue(void) const { return(m_open); } double CloseValue(void) const { return(m_close); } double HigthValue(void) const { return(m_high); } double LowValue(void) const { return(m_low); } uint CandleColorIncrement(void) const { return(m_clr_inc); } uint CandleColorDecrement(void) const { return(m_clr_dec); } int CandleWidth(void) const { return(m_width); } }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CCandle::CCandle(const double open,const double close,const double high,const double low, const int width,const uint clr_inc=0x000000,const uint clr_dec=0xF5F5F5): m_open(open),m_close(close),m_high(high),m_low(low), m_clr_inc(clr_inc),m_clr_dec(clr_dec),m_width(width) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CCandle::~CCandle(void) { }由于CCandle类是CObject类的后代,所有我们想画的烛台,我们都可以依次写入CArrayObj类的 对象中。这个数组将作为cbdata参数进入我们的自定义绘图方法。因此,蜡烛图的绘制方法将看起来如下。//+------------------------------------------------------------------+ //| Custom method for plot candles | //+------------------------------------------------------------------+ void PlotCandles(double &x[],double &y[],int size,CGraphic *graphic,CCanvas *canvas,void *cbdata) { //--- check obj CArrayObj *candles=dynamic_cast<CArrayObj*>(cbdata); if(candles==NULL || candles.Total()!=size) return; //--- plot candles for(int i=0; i<size; i++) { CCandle *candle=dynamic_cast<CCandle*>(candles.At(i)); if(candle==NULL) return; //--- primary calculate int xc=graphic.ScaleX(x[i]); int width_2=candle.CandleWidth()/2; int open=graphic.ScaleY(candle.OpenValue()); int close=graphic.ScaleY(candle.CloseValue()); int high=graphic.ScaleY(candle.HigthValue()); int low=graphic.ScaleY(candle.LowValue()); uint clr=(open<=close) ? candle.CandleColorIncrement() : candle.CandleColorDecrement(); //--- plot candle canvas.LineVertical(xc,high,low,0x000000); //--- plot candle real body canvas.FillRectangle(xc+width_2,open,xc-width_2,close,clr); canvas.Rectangle(xc+width_2,open,xc-width_2,close,0x000000); } }3.为了简单起见,所有的蜡烛图都将随机生成。于是我们依次生成10个蜡烛图,并将它们填入CArrayObj类对象。然后我们创建CGraphics对象,并在其中添加一条曲线,同时指定它将使用我们的PlotCandles函数来绘制。我们还需要改变Y轴的最大值和最小值,这样我们的蜡烛就能完全显现出来。//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { int count=10; int width=10; double x[]; double y[]; ArrayResize(x,count); ArrayResize(y,count); CArrayObj candles(); double max=0; double min=0; //--- create values for(int i=0; i<count; i++) { x[i] = i; y[i] = i; //--- calculate values double open=MathRound(50.0+(MathRand()/32767.0)*50.0); double close=MathRound(50.0+(MathRand()/32767.0)*50.0); double high=MathRound(MathMax(open,close)+(MathRand()/32767.0)*10.0); double low=MathRound(MathMin(open,close) -(MathRand()/32767.0)*10.0); //--- find max and min if(i==0 || max<high) max=high; if(i==0 || min>low) min=low; //--- create candle CCandle *candle=new CCandle(open,close,high,low,width); candles.Add(candle); } //--- create graphic CGraphic graphic; if(!graphic.Create(0,"CandleGraphic",0,30,30,780,380)) { graphic.Attach(0,"CandleGraphic"); } //--- create curve CCurve *curve=graphic.CurveAdd(x,y,CURVE_CUSTOM,"Candles"); //--- sets the curve properties curve.CustomPlotFunction(PlotCandles); curve.CustomPlotCBData(GetPointer(candles)); //--- sets the graphic properties graphic.YAxis().Max((int)max); graphic.YAxis().Min((int)min); //--- plot graphic.CurvePlotAll(); graphic.Update(); }结果是,我们得到了以下图表。 附加的文件: Canvas.mqh 304 kb Axis.mqh 12 kb ColorGenerator.mqh 4 kb Curve.mqh 23 kb Graphic.mqh 73 kb Candle.mq5 6 kb --- 2017.03.12 18:51 #54 @罗曼-科诺佩尔科在CGraphic::SetDefaultParameters函数中存在一个小错误。颜色的初始化应考虑到不透明度。void CGraphic::SetDefaultParameters(void) { ... ... //--- sets the default values for grid m_grid.clr_line=ColorToARGB(clrWhiteSmoke,255); m_grid.clr_axis_line=ColorToARGB(clrSilver,255); Roman Konopelko 2017.03.13 16:29 #55 o_o:@罗曼-科诺佩尔科在CGraphic::SetDefaultParameters函数中存在一个小错误。颜色的初始化应考虑到不透明度。 下午好,我已经修复了这一点,但不幸的是,这些编辑还没有进入构建阶段。 Vladimir Karputov 2017.06.13 13:40 #56 这个例子导致计算机冻结。我所做的:在编辑器中把指标放在图表上后,我玩了注释/不注释第87行和第88行的不同组合(当一次一个,当一起一个)。//+------------------------------------------------------------------+ //| tst.mq5 | //| Copyright © 2017, Vladimir Karputov | //| http://wmua.ru/slesar/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2017, Vladimir Karputov" #property link "http://wmua.ru/slesar/" #property version "1.000" #property description "Panel indicator: \"Evening Star\" pattern " #property description "search results for different periods" #property indicator_chart_window #property indicator_buffers 0 #property indicator_plots 0 #include <Graphics\Graphic.mqh> //--- object for creating graphs CGraphic my_graphic; //+------------------------------------------------------------------+ //| Global Variables | //+------------------------------------------------------------------+ bool m_first_start=false; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { if(!EventSetTimer(3)) if(!EventSetTimer(3)) if(!EventSetTimer(3)) { Print("Error create timer! THREE attempts!"); return(INIT_FAILED); } //--- canvas creation my_graphic.Create(0,"Evening Star Statistics",0,10,10,800,550); my_graphic.CurvePlotAll(); my_graphic.Update(); //--- m_first_start=false; //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { my_graphic.Destroy(); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { if(!m_first_start) { //--- revert access to arrays - do it like in timeseries ArraySetAsSeries(time,true); ArraySetAsSeries(open,true); ArraySetAsSeries(high,true); ArraySetAsSeries(low,true); ArraySetAsSeries(close,true); int size=ArraySize(time); double arrY[],arrX[]; ArrayResize(arrX,size); ArrayResize(arrY,size); for(int i=0; i<size;++i) { arrX[i]=(double)time[i]; arrY[i]=close[i]; } CCurve *curve_b=my_graphic.CurveAdd(arrX,arrY,CURVE_LINES,"Close"); CAxis *xAxis=my_graphic.XAxis(); // получаем ось X //---попеременно комбинирую (комментировать, раскомментировать) строки 87 //--- и 88 можно словить момент поглощения памяти и зависания компьютера //xAxis.AutoScale(false); //xAxis.Type(AXIS_TYPE_DATETIME); my_graphic.CurvePlotAll(); my_graphic.Update(); m_first_start=true; } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| Timer function | //+------------------------------------------------------------------+ void OnTimer() { } //+------------------------------------------------------------------+ 重复了两次成就。我没有记录行动的顺序。第三次是微不足道的,我不敢检查。已添加: build 1607 x64 附加的文件: tst.mq5 8 kb Vladimir Karputov 2017.06.14 09:06 #57 Vladimir Karputov:这个例子导致计算机冻结。我所做的:在编辑器中把指标放在图表上后,我玩了注释/不注释第87行和第88行的不同组合(当一次一个,当一起一个)。重复了两次成就。我没有记录行动的顺序。第三次是微不足道的,我不敢检查。已添加: build 1607 x64 今天重复了这个记录--死机挂起,设法看到内存消耗从2GB上升到5.5GB。似乎已经设法关闭了时间表,但电脑已经挂了五分钟。这一次我对数组的大小做了限制--不超过300个元素。正如你所看到的,它没有帮助🤔。 --- 2017.06.14 10:11 #58 debug说什么? Vladimir Karputov 2017.06.14 10:14 #59 o_o:debug说什么? Jbug没有得到它,我是这样做的:把一个指标悬停在空中,取消/注释了一两行,然后编译了。最后用平板电脑写作,笔记本坏了......。 Vladimir Karputov 2017.06.14 10:28 #60 Vladimir Karputov: gbug没有成功,我是这样做的:我把鼠标悬停在指标上,注释了/评论了一两行,然后编译了。最后用平板电脑写作,笔记本坏了......。 所以,笔记本在硬重启后又恢复了活力,但我不想再进行进一步的破坏性实验--笔记本上有几个专家顾问在运行,所以没有想抓紧时间冻结一整小时。 12345678910111213 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
在CGraphic类中,我按照你的要求,在所有地方都用uint替换了颜色类型。
此外,我还为CCanvas类添加了新的方法,它允许以指定的厚度绘制基元。
为了与CCanvas的创新保持一致,我扩展了CCurve的属性。
当用线条绘制曲线时,你现在可以指定线条的粗细和其末端的样式。
这真是太棒了。
对花键的处理(用贝塞尔曲线进行插值)进行了修改。它的实现已经从CGraphics类中直接移到了CCanvas中,这样就可以在图形库之外构建花样。
此外,还增加了渲染闭合花键的算法。
因此,CCanvas类 现在有两个新的公共方法。
这些方法允许以给定的样式和给定的厚度来绘制花键。
由于贝塞尔曲线相当精确地描述了圆和椭圆,因此没有明显的必要用新的方法来增强CCanvas类,以渲染具有给定厚度的这些基元。
基于PolygoneSmooth方法的贝塞尔曲线对椭圆进行逼近的例子。
结果。
实现图形库多功能性的另一个可能步骤:自定义曲线绘制模式CURVE_CUSTOM。
这种模式将消除继承CGraphic类和重载...Plot方法的需要,以便以不同于库的标准工具的方式绘制曲线。
为了实现这种模式CURVE_CUSTOM,新的属性将被添加到CCurve类。
它是基于一个新的指向PlotFucntion函数的指针。
这种方法为绘制地块提供了新的可能性。
让我们以CGraphics库为例来实现蜡烛图的绘制。
1.让我们创建一个容器类,其中将存储单个蜡烛的所有数据。
由于CCandle类是CObject类的后代,所有我们想画的烛台,我们都可以依次写入CArrayObj类的 对象中。这个数组将作为cbdata参数进入我们的自定义绘图方法。因此,蜡烛图的绘制方法将看起来如下。
3.为了简单起见,所有的蜡烛图都将随机生成。于是我们依次生成10个蜡烛图,并将它们填入CArrayObj类对象。然后我们创建CGraphics对象,并在其中添加一条曲线,同时指定它将使用我们的PlotCandles函数来绘制。我们还需要改变Y轴的最大值和最小值,这样我们的蜡烛就能完全显现出来。
结果是,我们得到了以下图表。
@罗曼-科诺佩尔科
在CGraphic::SetDefaultParameters函数中存在一个小错误。
颜色的初始化应考虑到不透明度。
@罗曼-科诺佩尔科
在CGraphic::SetDefaultParameters函数中存在一个小错误。
颜色的初始化应考虑到不透明度。
这个例子导致计算机冻结。我所做的:在编辑器中把指标放在图表上后,我玩了注释/不注释第87行和第88行的不同组合(当一次一个,当一起一个)。
重复了两次成就。我没有记录行动的顺序。第三次是微不足道的,我不敢检查。
已添加: build 1607 x64
这个例子导致计算机冻结。我所做的:在编辑器中把指标放在图表上后,我玩了注释/不注释第87行和第88行的不同组合(当一次一个,当一起一个)。
重复了两次成就。我没有记录行动的顺序。第三次是微不足道的,我不敢检查。
已添加: build 1607 x64
今天重复了这个记录--死机挂起,设法看到内存消耗从2GB上升到5.5GB。似乎已经设法关闭了时间表,但电脑已经挂了五分钟。
这一次我对数组的大小做了限制--不超过300个元素。正如你所看到的,它没有帮助🤔。
debug说什么?
debug说什么?
Jbug没有得到它,我是这样做的:把一个指标悬停在空中,取消/注释了一两行,然后编译了。最后用平板电脑写作,笔记本坏了......。
gbug没有成功,我是这样做的:我把鼠标悬停在指标上,注释了/评论了一两行,然后编译了。最后用平板电脑写作,笔记本坏了......。
所以,笔记本在硬重启后又恢复了活力,但我不想再进行进一步的破坏性实验--笔记本上有几个专家顾问在运行,所以没有想抓紧时间冻结一整小时。