//+------------------------------------------------------------------+ //| CGraphic.mqh | //| Copyright 2000-2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include #include "Curve.mqh" #include "Axis.mqh" #include "ColorGenerator.mqh" //--- tick position enum ENUM_MARK_POSITION { MARK_EXTERNAL, MARK_INTERNAL, MARK_MIDDLE }; //+------------------------------------------------------------------+ //| Structure CBackground | //| Usage: background on a two-dimensional graphics | //+------------------------------------------------------------------+ struct CBackground { uint clr; uint clr_main; uint clr_sub; string main; string sub; int size_main; int size_sub; }; //+------------------------------------------------------------------+ //| Structure CCurveHistory | //| Usage: history of curves on a two-dimensional graphics | //+------------------------------------------------------------------+ struct CCurveHistory { int name_width; int name_size; int symbol_size; int count_total; int count_points; int count_lines; int count_histogram; int count_custom; }; //+------------------------------------------------------------------+ //| Structure CGrid | //| Usage: grid on a two-dimensional graphics | //+------------------------------------------------------------------+ struct CGrid { uint clr_line; uint clr_background; uint clr_circle; uint clr_axis_line; uint clr_frame; int r_circle; bool has_circle; }; //+------------------------------------------------------------------+ //| Class CGraphic | //| Usage: class for drawing two-dimensional graphics | //+------------------------------------------------------------------+ class CGraphic { protected: CArrayObj m_arr_curves; CCanvas m_canvas; //--- parameters background int m_height; int m_width; //--- parameters work space int m_left; int m_right; int m_up; int m_down; //--- default parameters work space int m_left0; int m_right0; int m_up0; int m_down0; //--- size of dash on the axes int m_mark_size; //--- scaling parameters double m_dx; double m_dy; //--- element of graphic CAxis m_x; // x axis CAxis m_y; // y axis CGrid m_grid; // grid CBackground m_background; // background CCurveHistory m_history; // history //--- generates color curves CColorGenerator m_generator; //--- distance between the elements int m_gap; //--- coordinates and values for axes int m_xc[]; int m_yc[]; string m_xvalues[]; string m_yvalues[]; int m_xsize; int m_ysize; bool m_xupdate; bool m_yupdate; public: CGraphic(void); ~CGraphic(void); //--- gets width and height int Width(void) const { return(m_width); } int Height(void) const { return(m_height); } //--- gets or sets indents int IndentUp(void) const { return(m_up0); } void IndentUp(const int up) { m_up0=up; } int IndentDown(void) const { return(m_down0); } void IndentDown(const int down) { m_down0=down; } int IndentLeft(void) const { return(m_left0); } void IndentLeft(const int left) { m_left0=left; } int IndentRight(void) const { return(m_right0); } void IndentRight(const int right) { m_right0=right; } //--- gets or sets gap int GapSize(void) const { return(m_gap); } void GapSize(const int size) { m_gap=size; } //--- gets or sets major mark size int MajorMarkSize(void) const { return(m_mark_size); } void MajorMarkSize(const int size) { m_mark_size=size; } //--- axis properties CAxis *XAxis(void) { return GetPointer(m_x); } CAxis *YAxis(void) { return GetPointer(m_y); } //--- gets the curve history properties int HistoryNameWidth(void) const { return(m_history.name_width); } int HistoryNameSize(void) const { return(m_history.name_size); } int HistorySymbolSize(void) const { return(m_history.symbol_size); } //--- sets the curve history properties void HistoryNameWidth(const int width) { m_history.name_width=width; } void HistoryNameSize(const int size) { m_history.name_size=size; } void HistorySymbolSize(const int size) { m_history.symbol_size=size; } //--- gets the grid properties uint GridLineColor(void) const { return(m_grid.clr_line); } uint GridAxisLineColor(void) const { return(m_grid.clr_axis_line); } uint GridBackgroundColor(void) const { return(m_grid.clr_background); } int GridCircleRadius(void) const { return(m_grid.r_circle); } uint GridCircleColor(void) const { return(m_grid.clr_circle); } bool GridHasCircle(void) const { return(m_grid.has_circle); } //--- sets the grid properties void GridLineColor(const uint clr) { m_grid.clr_line=clr; } void GridAxisLineColor(const uint clr) { m_grid.clr_axis_line=clr; } void GridBackgroundColor(const uint clr) { m_grid.clr_background=clr; } void GridCircleRadius(const int r) { m_grid.r_circle=r; } void GridCircleColor(const uint clr) { m_grid.clr_circle=clr; } void GridHasCircle(const bool has) { m_grid.has_circle=has; } //--- gets the background properties uint BackgroundColor(void) const { return(m_background.clr); } uint BackgroundMainColor(void) const { return(m_background.clr_main); } uint BackgroundSubColor(void) const { return(m_background.clr_sub); } string BackgroundMain(void) const { return(m_background.main); } string BackgroundSub(void) const { return(m_background.sub); } int BackgroundMainSize(void) const { return(m_background.size_main); } int BackgroundSubSize(void) const { return(m_background.size_sub); } //--- sets the background properties void BackgroundColor(const uint clr) { m_background.clr=clr; } void BackgroundMainColor(const uint clr) { m_background.clr_main=clr; } void BackgroundSubColor(const uint clr) { m_background.clr_sub=clr; } void BackgroundMain(const string main) { m_background.main=main; } void BackgroundSub(const string sub) { m_background.sub=sub; } void BackgroundMainSize(const int size) { m_background.size_main=size; } void BackgroundSubSize(const int size) { m_background.size_sub=size; } //--- create/attach/destroy bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2); bool Attach(const long chart_id,const string objname); bool Attach(const long chart_id,const string objname,const int width,const int height); void Destroy(void); //--- main properties string ChartObjectName(void) const { return(m_canvas.ChartObjectName()); } string ResourceName(void) const { return(m_canvas.ResourceName()); } //--- redraw all object on screen bool Redraw(const bool rescale=false); //--- update object on screen void Update(const bool redraw=true); //--- methods for add new curve CCurve *CurveAdd(const double &y[],ENUM_CURVE_TYPE type,const string name=NULL); CCurve *CurveAdd(const double &x[],const double &y[],ENUM_CURVE_TYPE type,const string name=NULL); CCurve *CurveAdd(const CPoint2D &points[],ENUM_CURVE_TYPE type,const string name=NULL); CCurve *CurveAdd(CurveFunction function,const double from,const double to,const double step,ENUM_CURVE_TYPE type,const string name=NULL); CCurve *CurveAdd(const double &x[],const double &y[],const uint clr,ENUM_CURVE_TYPE type,const string name=NULL); CCurve *CurveAdd(const double &y[],const uint clr,ENUM_CURVE_TYPE type,const string name=NULL); CCurve *CurveAdd(const CPoint2D &points[],const uint clr,ENUM_CURVE_TYPE type,const string name=NULL); CCurve *CurveAdd(CurveFunction function,const double from,const double to,const double step,const uint clr,ENUM_CURVE_TYPE type,const string name=NULL); //--- methods for draw curve bool CurvePlotAll(void); bool CurvePlot(const int index); //--- methods for work with curves int CurvesTotal(void); CCurve *CurveGetByIndex(const int index); CCurve *CurveGetByName(const string name); bool CurveRemoveByIndex(const int index); bool CurveRemoveByName(const string name); //--- methods for add new elements bool MarksToAxisAdd(const double &marks[],const int mark_size,ENUM_MARK_POSITION position,const int dimension=0); void TextAdd(const int x,const int y,const string text,const uint clr,const uint alignment=0); void TextAdd(const CPoint &point,const string text,const uint clr,const uint alignment=0); void LineAdd(const int x1,const int y1,const int x2,const int y2,const uint clr,const uint style); void LineAdd(const CPoint &point1,const CPoint &point2,const uint clr,const uint style); //--- methods for settings text parameters bool FontSet(const string name,const int size,const uint flags=0,const uint angle=0) { return(m_canvas.FontSet(name,size,flags,angle)); } void FontGet(string &name,int &size,uint &flags,uint &angle) { m_canvas.FontGet(name,size,flags,angle); } //--- methods for convert real coordinates to pixel coordinates virtual int ScaleX(double x); virtual int ScaleY(double y); //--- methods for settings internal parameters void SetDefaultParameters(void); void ResetParameters(void); //--- method for calculate max and min values void CalculateMaxMinValues(void); protected: //--- methods for plot curve virtual void CustomPlot(CCurve *curve); virtual void PointsPlot(CCurve *curve); virtual void LinesPlot(CCurve *curve); virtual void PointsAndLinesPlot(CCurve *curve); virtual void StepsPlot(CCurve *curve); virtual void HistogramPlot(CCurve *curve); virtual void TrendLinePlot(CCurve *curve); //--- methods for create graphic elements virtual void CreateWorkspace(void); virtual void CreateGrid(void); virtual void CreateBackground(void); virtual void CreateXName(void); virtual void CreateYName(void); virtual void CreateAxes(void); virtual void CreateHistory(void); //--- methods for calculation internal parameters virtual void CalculateBoundaries(void); virtual void CalculateXAxis(void); virtual void CalculateYAxis(void); //--- services functions static double AxisFactorPrecision(const double min,const double max,const double step); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CGraphic::CGraphic(void) : m_height(0.0),m_width(0.0) { SetDefaultParameters(); } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CGraphic::~CGraphic(void) { } //+------------------------------------------------------------------+ //| Crete workspace on graphic | //+------------------------------------------------------------------+ void CGraphic::CreateWorkspace(void) { //--- coordinates int x1 = m_left; int y1 = m_up; int x2 = m_width-m_right; int y2 = m_height-m_down; //--- draw background of workspace m_canvas.FillRectangle(x1+1,y1+1,x2-1,y2-1,m_grid.clr_background); } //+------------------------------------------------------------------+ //| Create grid on graphic | //+------------------------------------------------------------------+ void CGraphic::CreateGrid(void) { int xc0=-1.0; int yc0=-1.0; for(int i=1; i0) m_canvas.LineHorizontal(m_left+1,m_width-m_right,yc0,m_grid.clr_axis_line); if(xc0>0) m_canvas.LineVertical(xc0,m_height-m_down-1,m_up+1,m_grid.clr_axis_line); //--- } //+------------------------------------------------------------------+ //| Create background, main and sub title | //+------------------------------------------------------------------+ void CGraphic::CreateBackground(void) { //--- coordinates int x1 = 0; int y1 = 0; int x2 = m_width; int y2 = m_height; //--- create background m_canvas.FillRectangle(0,0,m_width,m_up-1,m_background.clr); m_canvas.FillRectangle(0,m_height-m_down+1,m_width,m_height,m_background.clr); m_canvas.FillRectangle(0,m_up,m_left-1,m_height-m_down,m_background.clr); m_canvas.FillRectangle(m_width-m_right+1,m_up,m_width,m_height-m_down,m_background.clr); //--- set main title if(m_background.main!=NULL && m_background.size_main!=0) { m_canvas.FontSet("Arial",m_background.size_main,FW_HEAVY); int xc=int((x2+x1-m_canvas.TextWidth(m_background.main))/2.0); int yc=m_up-m_background.size_main-m_gap; m_canvas.TextOut(xc,yc,m_background.main,m_background.clr_main); m_canvas.FontFlagsSet(0); } //--- set sub title if(m_background.sub!=NULL && m_background.size_sub!=0) { m_canvas.FontSet("Arial",m_background.size_sub,FW_MEDIUM); int xc=int((x2+x1-m_canvas.TextWidth(m_background.sub))/2.0); int yc=m_height-m_down+m_mark_size+m_y.ValuesSize()+m_y.NameSize()+m_gap*3; m_canvas.TextOut(xc,yc,m_background.sub,m_background.clr_sub); m_canvas.FontFlagsSet(0); } } //+------------------------------------------------------------------+ //| Create x axis name on graphic | //+------------------------------------------------------------------+ void CGraphic::CreateXName(void) { if(m_x.NameSize()!=0 && m_x.Name()!=NULL) { m_canvas.FontSizeSet(m_x.NameSize()); int yc=m_height-m_down+m_mark_size+m_x.ValuesSize()+m_gap*2; m_canvas.TextOut((int)((m_width-m_canvas.TextWidth(m_x.Name()))/2.0),yc,m_x.Name(),m_x.Color()); } } //+------------------------------------------------------------------+ //| Create y axis name on graphic | //+------------------------------------------------------------------+ void CGraphic::CreateYName(void) { if(m_y.NameSize()!=0 && m_y.Name()!=NULL) { m_canvas.FontSizeSet(m_y.NameSize()); m_canvas.FontAngleSet(900); int xc=m_left-m_y.NameSize()-m_mark_size-m_y.ValuesWidth()-m_gap*2; m_canvas.TextOut(xc,(int)((m_height+m_canvas.TextWidth(m_y.Name()))/2.0),m_y.Name(),m_y.Color()); m_canvas.FontAngleSet(0); } } //+------------------------------------------------------------------+ //| Create axes on graphic | //+------------------------------------------------------------------+ void CGraphic::CreateAxes(void) { //--- int x1=m_left; int x2=m_left-m_mark_size; int y1=m_height-m_down; int y2=m_height-m_down+m_mark_size; //--- create frame m_canvas.Rectangle(m_left,m_up,m_width-m_right,m_height-m_down,m_grid.clr_frame); //--- set font y m_canvas.FontSet(m_y.ValuesFontName(),m_y.ValuesSize(),m_y.ValuesFontFlags(),m_y.ValuesFontAngle()); //--- create y axis for(int i=0; im_y.ValuesWidth()) { if(m_canvas.TextWidth("...")>m_y.ValuesWidth()) { yvalue=NULL; } else { while(m_canvas.TextWidth(yvalue+"...")>m_y.ValuesWidth()) { yvalue=StringSubstr(yvalue,0,StringLen(yvalue)-1); } yvalue+="..."; } } //--- draw mark and set y value int yi_width=m_canvas.TextWidth(yvalue); m_canvas.TextOut(m_left-yi_width-m_mark_size-m_gap,m_yc[i]-yh/2,yvalue,ColorToARGB(clrBlack),TA_LEFT); if(m_mark_size>0.0) m_canvas.LineHorizontal(x1,x2,m_yc[i],ColorToARGB(clrBlack)); } //--- set font x m_canvas.FontSet(m_x.ValuesFontName(),m_x.ValuesSize(),m_x.ValuesFontFlags(),m_x.ValuesFontAngle()); //--- create x axis for(int i=0; i0.0) m_canvas.LineVertical(m_xc[i],y1,y2,ColorToARGB(clrBlack)); } //--- } //+------------------------------------------------------------------+ //| Create graphic | //+------------------------------------------------------------------+ bool CGraphic::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2) { //--- check object name if(ObjectFind(chart,name)>=0) return(false); //--- preliminary calculation int width=x2-x1; int height=y2-y1; if(width>0 && height>0) { m_width=width; m_height=height; //--- create object if(!ObjectCreate(chart,name,OBJ_BITMAP_LABEL,subwin,0,0)) return(false); //--- customize object if(!ObjectSetInteger(chart,name,OBJPROP_XDISTANCE,x1) || !ObjectSetInteger(chart,name,OBJPROP_YDISTANCE,y1)) { ObjectDelete(chart,name); return(false); } //--- attach object if(!m_canvas.Attach(chart,name,width,height)) { ObjectDelete(chart,name); return(false); } } //--- success return(true); } //+------------------------------------------------------------------+ //| Attach new object with bitmap resource | //+------------------------------------------------------------------+ bool CGraphic::Attach(const long chart_id,const string objname) { if(m_canvas.Attach(chart_id,objname)) { m_width=m_canvas.Width(); m_height=m_canvas.Height(); //--- success return(true); } //--- failed return(false); } //+------------------------------------------------------------------+ //| Attach new object without bitmap resource | //+------------------------------------------------------------------+ bool CGraphic::Attach(const long chart_id,const string objname,const int width,const int height) { if(m_canvas.Attach(chart_id,objname,width,height)) { m_width=m_canvas.Width(); m_height=m_canvas.Height(); //--- success return(true); } //--- failed return(false); } //+------------------------------------------------------------------+ //| Remove graphic from chart | //+------------------------------------------------------------------+ void CGraphic::Destroy(void) { SetDefaultParameters(); m_generator.Reset(); m_canvas.Destroy(); } //+------------------------------------------------------------------+ //| Add new curve on graphic | //+------------------------------------------------------------------+ CCurve *CGraphic::CurveAdd(const double &y[],ENUM_CURVE_TYPE type,const string name=NULL) { return CurveAdd(y,m_generator.Next(),type,name); } //+------------------------------------------------------------------+ //| Add new curve on graphic | //+------------------------------------------------------------------+ CCurve *CGraphic::CurveAdd(const double &x[],const double &y[],ENUM_CURVE_TYPE type,const string name=NULL) { return CurveAdd(x,y,m_generator.Next(),type,name); } //+------------------------------------------------------------------+ //| Add new curve on graphic | //+------------------------------------------------------------------+ CCurve *CGraphic::CurveAdd(const CPoint2D &points[],ENUM_CURVE_TYPE type,const string name=NULL) { return CurveAdd(points,m_generator.Next(),type,name); } //+------------------------------------------------------------------+ //| Add new curve on graphic | //+------------------------------------------------------------------+ CCurve *CGraphic::CurveAdd(CurveFunction function,const double from,const double to,const double step,ENUM_CURVE_TYPE type,const string name=NULL) { return CurveAdd(function,from,to,step,m_generator.Next(),type,name); } //+------------------------------------------------------------------+ //| Add new curve on graphic | //+------------------------------------------------------------------+ CCurve *CGraphic::CurveAdd(const double &y[],const uint clr,ENUM_CURVE_TYPE type,const string name=NULL) { //--- create new curve CCurve *curve=new CCurve(y,clr,type,name); //--- set max and min values if(m_arr_curves.Total()==0) { if(m_x.AutoScale()) { m_x.Max(curve.XMax()); m_x.Min(curve.XMin()); } if(m_y.AutoScale()) { m_y.Max(curve.YMax()); m_y.Min(curve.YMin()); } m_xupdate = true; m_yupdate = true; } else { //--- find max of x if(m_x.Max()curve.XMin() && m_x.AutoScale()) { m_x.Min(curve.XMin()); m_xupdate=true; } //--- find max of y if(m_y.Max()curve.YMin() && m_y.AutoScale()) { m_y.Min(curve.YMin()); m_yupdate=true; } } //--- add curve m_arr_curves.Add(curve); return(curve); } //+------------------------------------------------------------------+ //| Add new curve on graphic | //+------------------------------------------------------------------+ CCurve *CGraphic::CurveAdd(const double &x[],const double &y[],const uint clr,ENUM_CURVE_TYPE type,const string name=NULL) { int xSize = ArraySize(x); int ySize = ArraySize(y); //--- check if(xSize!=ySize) return(NULL); //--- create new curve CCurve *curve=new CCurve(x,y,clr,type,name); //--- set max and min values if(m_arr_curves.Total()==0) { if(m_x.AutoScale()) { m_x.Max(curve.XMax()); m_x.Min(curve.XMin()); } if(m_y.AutoScale()) { m_y.Max(curve.YMax()); m_y.Min(curve.YMin()); } m_xupdate = true; m_yupdate = true; } else { //--- find max of x if(m_x.Max()curve.XMin() && m_x.AutoScale()) { m_x.Min(curve.XMin()); m_xupdate=true; } //--- find max of y if(m_y.Max()curve.YMin() && m_y.AutoScale()) { m_y.Min(curve.YMin()); m_yupdate=true; } } //--- add curve m_arr_curves.Add(curve); return(curve); } //+------------------------------------------------------------------+ //| Add new curve on graphic | //+------------------------------------------------------------------+ CCurve *CGraphic::CurveAdd(const CPoint2D &points[],const uint clr,ENUM_CURVE_TYPE type,const string name=NULL) { //--- create new curve CCurve *curve=new CCurve(points,clr,type,name); //--- set max and min values if(m_arr_curves.Total()==0) { if(m_x.AutoScale()) { m_x.Max(curve.XMax()); m_x.Min(curve.XMin()); } if(m_y.AutoScale()) { m_y.Max(curve.YMax()); m_y.Min(curve.YMin()); } m_xupdate = true; m_yupdate = true; } else { //--- find max of x if(m_x.Max()curve.XMin() && m_x.AutoScale()) { m_x.Min(curve.XMin()); m_xupdate=true; } //--- find max of y if(m_y.Max()curve.YMin() && m_y.AutoScale()) { m_y.Min(curve.YMin()); m_yupdate=true; } } //--- add curve m_arr_curves.Add(curve); return(curve); } //+------------------------------------------------------------------+ //| Add new curve on graphic | //+------------------------------------------------------------------+ CCurve *CGraphic::CurveAdd(CurveFunction function,const double from,const double to,const double step,const uint clr,ENUM_CURVE_TYPE type,const string name=NULL) { //--- check if(from>=to || step<=0 || step>=MathAbs(to-from)) return(NULL); //--- create new curve CCurve *curve=new CCurve(function,from,to,step,clr,type,name); //--- set max and min values if(m_arr_curves.Total()==0) { if(m_x.AutoScale()) { m_x.Max(curve.XMax()); m_x.Min(curve.XMin()); } if(m_y.AutoScale()) { m_y.Max(curve.YMax()); m_y.Min(curve.YMin()); } m_xupdate = true; m_yupdate = true; } else { //--- find max of x if(m_x.Max()curve.XMin() && m_x.AutoScale()) { m_x.Min(curve.XMin()); m_xupdate=true; } //--- find max of y if(m_y.Max()curve.YMin() && m_y.AutoScale()) { m_y.Min(curve.YMin()); m_yupdate=true; } } //--- add curve m_arr_curves.Add(curve); return(curve); } //+------------------------------------------------------------------+ //| Add ticks to current graphic | //+------------------------------------------------------------------+ bool CGraphic::MarksToAxisAdd(const double &marks[],const int mark_size,ENUM_MARK_POSITION position,const int dimension=0) { int originalX=m_left; int originalY=m_height-m_down; //--- check dimension if(dimension==0) { int y1=m_height-m_down; int y2=m_height-m_down; //--- calculate y coordinates for marks switch(position) { case MARK_INTERNAL: y1-=mark_size; break; case MARK_EXTERNAL: y2+=mark_size; break; case MARK_MIDDLE: y1-=mark_size/2; y2+=mark_size/2; break; } //--- draw marks to x axis for(int i=0; i(m_arr_curves.At(index)); if(CheckPointer(curve)==POINTER_DYNAMIC) curve.Visible(true); else return(false); //--- ResetParameters(); CalculateBoundaries(); //--- update axes if(m_xupdate) CalculateXAxis(); if(m_yupdate) CalculateYAxis(); //--- create workspace and grid CreateWorkspace(); CreateGrid(); //--- draw all curves for(int i=0; i(m_arr_curves.At(i)); if(CheckPointer(curve)!=POINTER_DYNAMIC) return(false); if(!curve.Visible()) continue; //--- draws depending on the type of curve switch(curve.Type()) { case CURVE_CUSTOM: CustomPlot(curve); break; case CURVE_POINTS: PointsPlot(curve); break; case CURVE_LINES: LinesPlot(curve); break; case CURVE_POINTS_AND_LINES: PointsAndLinesPlot(curve); break; case CURVE_STEPS: StepsPlot(curve); break; case CURVE_HISTOGRAM: HistogramPlot(curve); break; case CURVE_NONE: break; } //--- draw trend line if(curve.TrendLineVisible()) TrendLinePlot(curve); } //--- create background CreateBackground(); //--- create names for axes CreateXName(); CreateYName(); //--- create axes CreateAxes(); //--- create history CreateHistory(); //--- success return(true); } //+------------------------------------------------------------------+ //| Redraw grahic | //+------------------------------------------------------------------+ bool CGraphic::Redraw(const bool rescale=false) { ResetParameters(); CalculateBoundaries(); if(rescale) { CalculateMaxMinValues(); } //--- update axes if(m_xupdate) CalculateXAxis(); if(m_yupdate) CalculateYAxis(); //--- create workspace and grid CreateWorkspace(); CreateGrid(); //--- draw all curves for(int i=0; i(m_arr_curves.At(i)); if(CheckPointer(curve)!=POINTER_DYNAMIC) return(false); if(!curve.Visible()) continue; //--- draws depending on the type of curve switch(curve.Type()) { case CURVE_CUSTOM: CustomPlot(curve); break; case CURVE_POINTS: PointsPlot(curve); break; case CURVE_LINES: LinesPlot(curve); break; case CURVE_POINTS_AND_LINES: PointsAndLinesPlot(curve); break; case CURVE_STEPS: StepsPlot(curve); break; case CURVE_HISTOGRAM: HistogramPlot(curve); break; case CURVE_NONE: break; } //--- draw trend line if(curve.TrendLineVisible()) TrendLinePlot(curve); } //--- create background CreateBackground(); //--- create names for axes CreateXName(); CreateYName(); //--- create axes CreateAxes(); //--- create hictory CreateHistory(); //--- success return(true); } //+------------------------------------------------------------------+ //| Update graphic on screen (redraw) | //+------------------------------------------------------------------+ void CGraphic::Update(const bool redraw=true) { m_canvas.Update(redraw); } //+------------------------------------------------------------------+ //| Gets the number of curves on the graphic | //+------------------------------------------------------------------+ int CGraphic::CurvesTotal(void) { return(m_arr_curves.Total()); } //+------------------------------------------------------------------+ //| Gets the curve in the specified index | //+------------------------------------------------------------------+ CCurve *CGraphic::CurveGetByIndex(const int index) { return(m_arr_curves.At(index)); } //+------------------------------------------------------------------+ //| Gets the curve by name | //+------------------------------------------------------------------+ CCurve *CGraphic::CurveGetByName(const string name) { //--- try to find curve by name for(int i=0; i(m_arr_curves.At(i)); if(curve.Name()==name) return(curve); } //--- failed return(NULL); } //+------------------------------------------------------------------+ //| Remove the curve in the specified index | //+------------------------------------------------------------------+ bool CGraphic::CurveRemoveByIndex(const int index) { CCurve *curve=dynamic_cast(m_arr_curves.Detach(index)); if(CheckPointer(curve)==POINTER_DYNAMIC) { delete curve; return(true); } else { return(false); } } //+------------------------------------------------------------------+ //| Remove the curve by name | //+------------------------------------------------------------------+ bool CGraphic::CurveRemoveByName(const string name) { for(int i=0; i0) { switch(curve.PointsType()) { case POINT_CIRCLE: { //--- draw fill circle if(curve.PointsFill()) m_canvas.FillCircle(xc,yc,r,clr1); //--- draw circle m_canvas.CircleWu(xc,yc,r,clr0); break; } case POINT_SQUARE: { //--- draw square m_canvas.Rectangle(xc-r,yc-r,xc+r,yc+r,clr0); //--- draw fill square if(curve.PointsFill()) m_canvas.FillRectangle(xc-r+1,yc-r+1,xc+r-1,yc+r-1,clr1); break; } case POINT_DIAMOND: { int xc1=xc+1-r; int yc1=yc; int xc2=xc; int yc2=yc+1-r; //--- draw diamond m_canvas.Line(xc-r,yc,xc,yc-r,clr0); m_canvas.Line(xc,yc-r,xc+r,yc,clr0); m_canvas.Line(xc+r,yc,xc,yc+r,clr0); m_canvas.Line(xc,yc+r,xc-r,yc,clr0); //--- draw fill diamond if(curve.PointsFill()) { int count=(curve.PointsSize()%2==0) ? curve.PointsSize()-1 : curve.PointsSize()-2; for(int j=0; j2 && tension>0.0 && tension<=1.0) m_canvas.PolylineSmooth(xc,yc,curve.Color(),curve.LinesWidth(),curve.LinesStyle(),curve.LinesEndStyle(),tension,curve.LinesSmoothStep()); else if(size>1) m_canvas.PolylineThick(xc,yc,curve.Color(),curve.LinesWidth(),curve.LinesStyle(),curve.LinesEndStyle()); else if(size==1) m_canvas.PixelSet(xc[0],yc[0],curve.Color()); } else { int index=0; for(int j=0; j<=ArraySize(discontinuity); j++) { double xj[]; double yj[]; int sizej=0; if(j==0) { sizej=discontinuity[0]; ArrayCopy(xj,x,0,0,sizej); ArrayCopy(yj,y,0,0,sizej); } else if(j==ArraySize(discontinuity)) { sizej=size-discontinuity[j-1]-1; ArrayCopy(xj,x,0,discontinuity[j-1]+1,sizej); ArrayCopy(yj,y,0,discontinuity[j-1]+1,sizej); } else { sizej=discontinuity[j]-discontinuity[j-1]-1; ArrayCopy(xj,x,0,discontinuity[j-1]+1,sizej); ArrayCopy(yj,y,0,discontinuity[j-1]+1,sizej); } //--- calculate coordinates path of curve ArrayResize(xc,sizej,size); ArrayResize(yc,sizej,size); for(int i=0; i2 && tension>0.0 && tension<=1.0) m_canvas.PolylineSmooth(xc,yc,curve.Color(),curve.LinesWidth(),curve.LinesStyle(),curve.LinesEndStyle(),tension,curve.LinesSmoothStep()); else if(sizej>1) m_canvas.PolylineThick(xc,yc,curve.Color(),curve.LinesWidth(),curve.LinesStyle(),curve.LinesEndStyle()); else if(sizej==1) m_canvas.PixelSet(xc[0],yc[0],curve.Color()); } } } //+------------------------------------------------------------------+ //| Draws a curve points over lines | //+------------------------------------------------------------------+ void CGraphic::PointsAndLinesPlot(CCurve *curve) { LinesPlot(curve); PointsPlot(curve); } //+------------------------------------------------------------------+ //| Draws a curve steps | //+------------------------------------------------------------------+ void CGraphic::StepsPlot(CCurve *curve) { int size=curve.Size(); double x[],y[]; //--- gets the coordinates of the curve curve.GetX(x); curve.GetY(y); //--- coordinates int xc[],yc[]; size=(size*2)-1; ArrayResize(xc,size); ArrayResize(yc,size); int index=0; if(curve.StepsDimension()==0) { //--- x dimension for(int i=0; iyc0 && yc0>0) ? yc0 : originalY; //--- if(yc1>yc2) yc2++; else yc2--; //--- m_canvas.FillRectangle(xc1,yc1,xc2,yc2,clr); } //--- } //+------------------------------------------------------------------+ //| Draws a trend line for curve | //+------------------------------------------------------------------+ void CGraphic::TrendLinePlot(CCurve *curve) { //--- simple linear regression double coeff[]; curve.TrendLineCoefficients(coeff); //--- calculate coordinates double x0=curve.XMin(); double x1=curve.XMax(); double y0=coeff[0]*x0+coeff[1]; double y1=coeff[0]*x1+coeff[1]; //--- coordinates in pixels int xc0=ScaleX(x0); int xc1=ScaleX(x1); int yc0=ScaleY(y0); int yc1=ScaleY(y1); uint clr=curve.Color(); //--- draw line m_canvas.LineWu(xc0,yc0,xc1,yc1,curve.TrendLineColor()); } //+------------------------------------------------------------------+ //| Create history of curves in the right side of the graphic | //+------------------------------------------------------------------+ void CGraphic::CreateHistory(void) { for(int i=0; i(m_arr_curves.At(i)); //--- check if(CheckPointer(curve)!=POINTER_DYNAMIC) return; if(!curve.Visible()) continue; //--- calculate y coordinate int yc=m_up+m_history.name_size/2+m_history.name_size*m_history.count_total; //--- gets the curve name string name=curve.Name(); //--- draw symbol switch(curve.Type()) { case CURVE_STEPS: case CURVE_POINTS_AND_LINES: case CURVE_LINES: { //--- coordinates int xc1=m_width-m_right+m_gap; int xc2=m_width-m_right+m_gap+m_history.symbol_size; if(m_history.symbol_size>0) m_canvas.LineWu(xc1,yc,xc2,yc,curve.Color(),curve.LinesStyle()); if(curve.Type()==CURVE_LINES) { if(name==NULL) { name="Lines "+IntegerToString(m_history.count_lines++); curve.Name(name); } break; } else if(curve.Type()==CURVE_STEPS) { if(name==NULL) { name="Steps "+IntegerToString(m_history.count_lines++); curve.Name(name); } break; } } case CURVE_POINTS : { //--- coordinates int xc=m_width-m_right+m_gap+m_history.symbol_size/2; int r=(m_history.symbol_size)/3; if(r>0) { switch(curve.PointsType()) { case POINT_CIRCLE: { //--- draw fill circle if(curve.PointsFill()) m_canvas.FillCircle(xc,yc,r,curve.PointsColor()); //--- draw circle m_canvas.CircleWu(xc,yc,r,curve.Color()); break; } case POINT_SQUARE: { //--- draw square m_canvas.Rectangle(xc-r,yc-r,xc+r,yc+r,curve.Color()); //--- draw fill square if(curve.PointsFill()) m_canvas.FillRectangle(xc-r+1,yc-r+1,xc+r-1,yc+r-1,curve.PointsColor()); break; } case POINT_DIAMOND: { int xc1=xc+1-r; int yc1=yc; int xc2=xc; int yc2=yc+1-r; //--- draw diamond m_canvas.Line(xc-r,yc,xc,yc-r,curve.Color()); m_canvas.Line(xc,yc-r,xc+r,yc,curve.Color()); m_canvas.Line(xc+r,yc,xc,yc+r,curve.Color()); m_canvas.Line(xc,yc+r,xc-r,yc,curve.Color()); //--- draw fill diamond if(curve.PointsFill()) { int count=((r*2)%2==0) ? (r*2)-1 : (r*2)-2; for(int j=0; j0) m_canvas.PixelSet(xc,yc,curve.Color()); } if(curve.Type()==CURVE_POINTS) { if(name==NULL) { name="Points "+IntegerToString(m_history.count_points++); curve.Name(name); } } else if(curve.Type()==CURVE_POINTS_AND_LINES) { if(name==NULL) { name="Points and Lines "+IntegerToString(m_history.count_points++); curve.Name(name); } } break; } case CURVE_HISTOGRAM: { //--- coordinates int xc1=m_width-m_right+m_gap+m_history.symbol_size/6; int yc1=yc-m_history.symbol_size*1/3; int xc2=m_width-m_right+m_gap+(m_history.symbol_size*5)/6; int yc2=yc+m_history.symbol_size*1/3; if(m_history.symbol_size>0) m_canvas.FillRectangle(xc1,yc1,xc2,yc2,curve.Color()); if(name==NULL) { name="Histogram "+IntegerToString(m_history.count_histogram++); curve.Name(name); } break; } case CURVE_CUSTOM: { if(name==NULL) { name="Custom "+IntegerToString(m_history.count_custom++); curve.Name(name); } break; } }; //--- trim the name m_canvas.FontSet("arial",m_history.name_size); if(m_canvas.TextWidth(name)>m_history.name_width) { if(m_canvas.TextWidth("...")>m_history.name_width) { name=NULL; } else { while(m_canvas.TextWidth(name+"...")>m_history.name_width) name=StringSubstr(name,0,StringLen(name)-1); name+="..."; } } //--- coordinates int xct=m_width-m_right+2*m_gap+m_history.symbol_size; int yct=yc-m_history.name_size/2; //--- draw text m_canvas.TextOut(xct,yct,name,ColorToARGB(clrBlack)); m_history.count_total++; } } //+------------------------------------------------------------------+ //| Reset current parameters on graphic | //+------------------------------------------------------------------+ void CGraphic::SetDefaultParameters(void) { //--- sets the general default values m_xupdate=false; m_yupdate=false; m_xsize=0; m_ysize=0; //--- sets the default values for boundaries m_left0=0; m_right0=5; m_up0=5; m_down0=0; //--- sets the default values for graphic m_mark_size=3; m_gap=4; //--- sets the default values for history m_history.name_width=60; m_history.symbol_size=12; m_history.name_size=12; m_history.count_points=0; m_history.count_lines=0; m_history.count_histogram=0; m_history.count_custom=0; //--- sets the default values for x and y axis m_x.Name(NULL); m_y.Name(NULL); //--- sets the default values for grid m_grid.clr_line=clrWhiteSmoke; m_grid.clr_axis_line=clrSilver; m_grid.clr_frame=clrBlack; m_grid.clr_background=clrWhite; m_grid.r_circle=0; m_grid.clr_circle=clrWhite; m_grid.has_circle=false; //--- sets the default values for background m_background.clr=clrWhite; m_background.clr_main= clrBlack; m_background.clr_sub = clrBlack; m_background.main= NULL; m_background.sub = NULL; m_background.size_main= 0; m_background.size_sub = 0; } //+------------------------------------------------------------------+ //| Reset parametres | //+------------------------------------------------------------------+ void CGraphic::ResetParameters(void) { //--- reset boundaries m_left=m_left0; m_right=m_right0; m_up=m_up0; m_down=m_down0; //--- reset curve of history m_history.count_total=0; } //+------------------------------------------------------------------+ //| Calculate boundaries for workspace | //+------------------------------------------------------------------+ void CGraphic::CalculateBoundaries(void) { if(m_width>0 && m_height>0) { m_right+=m_history.symbol_size+m_history.name_width+3*m_gap; m_up+=m_background.size_main+2*m_gap; m_down+=m_background.size_sub+m_x.ValuesSize()+m_x.NameSize()+4*m_gap; m_left+=m_y.NameSize()+m_mark_size+m_y.ValuesWidth()+4*m_gap; } else { ZeroMemory(m_right); ZeroMemory(m_up); ZeroMemory(m_down); ZeroMemory(m_left); } } //+------------------------------------------------------------------+ //| Calculate the min and max values for both axes on all curves | //+------------------------------------------------------------------+ void CGraphic::CalculateMaxMinValues(void) { int size=m_arr_curves.Total(); double xmax=0.0; double xmin=0.0; double ymax=0.0; double ymin=0.0; if(size>0) { bool valid=false; for(int i=0; i(m_arr_curves.At(i)); if(CheckPointer(curve)==POINTER_DYNAMIC) { if(!valid) { xmax = curve.XMax(); xmin = curve.XMin(); ymax = curve.YMax(); ymin = curve.YMin(); valid=true; } else { //--- find max of x if(xmaxcurve.XMin()) xmin=curve.XMin(); //--- find max of y if(ymaxcurve.YMin()) ymin=curve.YMin(); } } } } if(m_x.AutoScale()) { m_x.Max(xmax); m_x.Min(xmin); } if(m_y.AutoScale()) { m_y.Max(ymax); m_y.Min(ymin); } m_xupdate=true; m_yupdate=true; } //+------------------------------------------------------------------+ //| Calculate coordinates and values for x axis | //+------------------------------------------------------------------+ void CGraphic::CalculateXAxis(void) { //--- m_x.SelectAxisScale(); //--- gets the axis proprties double max = m_x.Max(); double min = m_x.Min(); double step= m_x.Step(); ENUM_AXIS_TYPE xtype=m_x.Type(); string xformat=m_x.ValuesFormat()==NULL ? "%.7g" : m_x.ValuesFormat(); int xmode=m_x.ValuesDateTimeMode(); DoubleToStringFunction xfunc=m_x.ValuesFunctionFormat(); void *xcbdata=m_x.ValuesFunctionFormatCBData(); //--- calculate scaling parameters double xf1=m_left; double xf2=m_width-m_right; //--- double x_size=max-min; double xf_size=xf2-xf1; //--- keep scaling parameters m_dx=xf_size/x_size; //--- calclulate size m_xsize=(int)MathRound((max-min)/step)+1; ArrayResize(m_xc,m_xsize); ArrayResize(m_xvalues,m_xsize); //--- gets the factor precision double factor=AxisFactorPrecision(min,max,step); for(int i=0; imax) x=max; //--- calculate real coordinate if(i==0) m_xc[i]=m_left; else if(i==m_xsize-1) m_xc[i]=m_width-m_right; else m_xc[i]=m_left+(int)((x-min)*m_dx); //--- create values names switch(xtype) { case AXIS_TYPE_DOUBLE: { m_xvalues[i]=StringFormat(xformat,x); break; } case AXIS_TYPE_DATETIME: { m_xvalues[i]=TimeToString((datetime)x,xmode); break; } case AXIS_TYPE_CUSTOM: { m_xvalues[i]=(xfunc==NULL) ? NULL : xfunc(x,xcbdata); break; } }; } //--- m_xupdate=false; } //+------------------------------------------------------------------+ //| Calculate coordinates and values for y axis | //+------------------------------------------------------------------+ void CGraphic::CalculateYAxis(void) { //--- m_y.SelectAxisScale(); //--- gets the axis proprties double max = m_y.Max(); double min = m_y.Min(); double step= m_y.Step(); ENUM_AXIS_TYPE ytype=m_y.Type(); string yformat=m_y.ValuesFormat()==NULL ? "%.7g" : m_y.ValuesFormat(); int ymode=m_y.ValuesDateTimeMode(); DoubleToStringFunction yfunc=m_y.ValuesFunctionFormat(); void *ycbdata=m_y.ValuesFunctionFormatCBData(); //--- calculate scaling parameters double yf1=m_up; double yf2=m_height-m_down; //--- double y_size=max-min; double yf_size=yf2-yf1; //--- keep scaling parameters m_dy=yf_size/y_size; //--- calclulate size m_ysize=(int)MathRound((max-min)/step)+1; ArrayResize(m_yc,m_ysize); ArrayResize(m_yvalues,m_ysize); //--- gets the factor precision double factor=AxisFactorPrecision(min,max,step); for(int i=0; imax) y=max; //--- calculate real coordinate if(i==0) m_yc[i]=m_height-m_down; else if(i==m_ysize-1) m_yc[i]=m_up; else m_yc[i]=m_height-m_down-(int)((y-min)*m_dy); //--- create values names switch(ytype) { case AXIS_TYPE_DOUBLE: { m_yvalues[i]=StringFormat(yformat,y); StringTrimLeft(m_yvalues[i]); StringTrimRight(m_yvalues[i]); break; } case AXIS_TYPE_DATETIME: { m_yvalues[i]=TimeToString((datetime)y,ymode); break; } case AXIS_TYPE_CUSTOM: { m_yvalues[i]=(yfunc==NULL) ? NULL : yfunc(y,ycbdata); break; } }; } //--- m_yupdate=false; } //+------------------------------------------------------------------+ //| Gets the factor precision for calculation error of control values| //| on axis | //+------------------------------------------------------------------+ double CGraphic::AxisFactorPrecision(const double min,const double max,const double step) { static const double big_value=4097.0; //--- create some big values based on control values double big_min=big_value*min; double big_max=big_value*max; double big_step=big_value*step; //--- gets the difference between big values and their control values double delta_min=big_min-min; double delta_max=big_max-max; double delta_step=big_step-step; //--- gets the calculating error of control values double error_min=MathAbs(min-(big_min-delta_min)); double error_max=MathAbs(max-(big_max-delta_max)); double error_step=MathAbs(step-(big_step-delta_step)); //--- get max error double error=MathMax(MathMax(error_min,error_max),error_step); //--- calculate factor double factor=1.0; if(error!=0) { double log10_val=MathLog10(MathAbs(error)); log10_val=(log10_val>0) ? MathCeil(log10_val) : MathFloor(log10_val); if(log10_val<=-308) factor=1e-308; else if(log10_val>=308) factor=1e308; else factor=MathPow(10,log10_val); } return(factor); } //+------------------------------------------------------------------+ //| Create graphic of one curve and return resource name | //+------------------------------------------------------------------+ string GraphPlot(const double &y[],ENUM_CURVE_TYPE type=CURVE_POINTS,string objname=NULL) { CGraphic graphic; ulong width = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); ulong height= ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); //--- create graphic bool res=false; objname = (objname==NULL) ? "Graphic" : objname; if(ObjectFind(0,objname)>=0) res=graphic.Attach(0,objname); else res=graphic.Create(0,objname,0,65,45,(int)(0.6*width),(int)(0.65*height)); if(!res) return(NULL); //--- add curves graphic.CurveAdd(y,type); //--- plot curves graphic.CurvePlotAll(); graphic.Update(); //--- return resource name return graphic.ChartObjectName(); } //+------------------------------------------------------------------+ //| Create graphic of one curve and return resource name | //+------------------------------------------------------------------+ string GraphPlot(const double &x[],const double &y[],ENUM_CURVE_TYPE type=CURVE_POINTS,string objname=NULL) { CGraphic graphic; ulong width = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); ulong height= ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); //--- create graphic bool res=false; objname = (objname==NULL) ? "Graphic" : objname; if(ObjectFind(0,objname)>=0) res=graphic.Attach(0,objname); else res=graphic.Create(0,objname,0,65,45,(int)(0.6*width),(int)(0.65*height)); if(!res) return(NULL); //--- add curves graphic.CurveAdd(x,y,type); //--- plot curves graphic.CurvePlotAll(); graphic.Update(); //--- return resource name return graphic.ChartObjectName(); } //+------------------------------------------------------------------+ //| Create graphic of two curve and return resource name | //+------------------------------------------------------------------+ string GraphPlot(const double &x1[],const double &y1[],const double &x2[],const double &y2[],ENUM_CURVE_TYPE type=CURVE_POINTS,string objname=NULL) { CGraphic graphic; ulong width = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); ulong height= ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); //--- create graphic bool res=false; objname = (objname==NULL) ? "Graphic" : objname; if(ObjectFind(0,objname)>=0) res=graphic.Attach(0,objname); else res=graphic.Create(0,objname,0,65,45,(int)(0.6*width),(int)(0.65*height)); if(!res) return(NULL); //--- add curves graphic.CurveAdd(x1,y1,type); graphic.CurveAdd(x2,y2,type); //--- plot curves graphic.CurvePlotAll(); graphic.Update(); //--- return resource name return graphic.ChartObjectName(); } //+------------------------------------------------------------------+ //| Create graphic of three curve and return resource name | //+------------------------------------------------------------------+ string GraphPlot(const double &x1[],const double &y1[],const double &x2[],const double &y2[],const double &x3[],const double &y3[],ENUM_CURVE_TYPE type=CURVE_POINTS,string objname=NULL) { CGraphic graphic; ulong width = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); ulong height= ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); //--- create graphic bool res=false; objname = (objname==NULL) ? "Graphic" : objname; if(ObjectFind(0,objname)>=0) res=graphic.Attach(0,objname); else res=graphic.Create(0,objname,0,65,45,(int)(0.6*width),(int)(0.65*height)); if(!res) return(NULL); //--- add curves graphic.CurveAdd(x1,y1,type); graphic.CurveAdd(x2,y2,type); graphic.CurveAdd(x3,y3,type); //--- plot curves graphic.CurvePlotAll(); graphic.Update(); //--- return resource name return graphic.ChartObjectName(); } //+------------------------------------------------------------------+ //| Create graphic of one curve and return resource name | //+------------------------------------------------------------------+ string GraphPlot(const CPoint2D &points[],ENUM_CURVE_TYPE type=CURVE_POINTS,string objname=NULL) { CGraphic graphic; ulong width = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); ulong height= ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); //--- create graphic bool res=false; objname = (objname==NULL) ? "Graphic" : objname; if(ObjectFind(0,objname)>=0) res=graphic.Attach(0,objname); else res=graphic.Create(0,objname,0,65,45,(int)(0.6*width),(int)(0.65*height)); if(!res) return(NULL); //--- add curves graphic.CurveAdd(points,type); //--- plot curves graphic.CurvePlotAll(); graphic.Update(); //--- return resource name return graphic.ChartObjectName(); } //+------------------------------------------------------------------+ //| Create graphic of two curve and return resource name | //+------------------------------------------------------------------+ string GraphPlot(const CPoint2D &points1[],const CPoint2D &points2[],ENUM_CURVE_TYPE type=CURVE_POINTS,string objname=NULL) { CGraphic graphic; ulong width = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); ulong height= ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); //--- create graphic bool res=false; objname = (objname==NULL) ? "Graphic" : objname; if(ObjectFind(0,objname)>=0) res=graphic.Attach(0,objname); else res=graphic.Create(0,objname,0,65,45,(int)(0.6*width),(int)(0.65*height)); if(!res) return(NULL); //--- add curves graphic.CurveAdd(points1,type); graphic.CurveAdd(points2,type); //--- plot curves graphic.CurvePlotAll(); graphic.Update(); //--- return resource name return graphic.ChartObjectName(); } //+------------------------------------------------------------------+ //| Create graphic of three curve and return resource name | //+------------------------------------------------------------------+ string GraphPlot(const CPoint2D &points1[],const CPoint2D &points2[],const CPoint2D &points3[],ENUM_CURVE_TYPE type=CURVE_POINTS,string objname=NULL) { CGraphic graphic; ulong width = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); ulong height= ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); //--- create graphic bool res=false; objname = (objname==NULL) ? "Graphic" : objname; if(ObjectFind(0,objname)>=0) res=graphic.Attach(0,objname); else res=graphic.Create(0,objname,0,65,45,(int)(0.6*width),(int)(0.65*height)); if(!res) return(NULL); //--- add curves graphic.CurveAdd(points1,type); graphic.CurveAdd(points2,type); graphic.CurveAdd(points3,type); //--- plot curves graphic.CurvePlotAll(); graphic.Update(); //--- return resource name return graphic.ChartObjectName(); } //+------------------------------------------------------------------+ //| Create graphic of one curve and return resource name | //+------------------------------------------------------------------+ string GraphPlot(CurveFunction function,const double from,const double to,const double step,ENUM_CURVE_TYPE type=CURVE_POINTS,string objname=NULL) { CGraphic graphic; ulong width = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); ulong height= ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); //--- create graphic bool res=false; objname = (objname==NULL) ? "Graphic" : objname; if(ObjectFind(0,objname)>=0) res=graphic.Attach(0,objname); else res=graphic.Create(0,objname,0,65,45,(int)(0.6*width),(int)(0.65*height)); if(!res) return(NULL); //--- add curves graphic.CurveAdd(function,from,to,step,type); //--- plot curves graphic.CurvePlotAll(); graphic.Update(); //--- return resource name return graphic.ChartObjectName(); } //+------------------------------------------------------------------+ //| Create graphic of two curve and return resource name | //+------------------------------------------------------------------+ string GraphPlot(CurveFunction function1,CurveFunction function2,const double from,const double to,const double step,ENUM_CURVE_TYPE type=CURVE_POINTS,string objname=NULL) { CGraphic graphic; ulong width = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); ulong height= ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); //--- create graphic bool res=false; objname = (objname==NULL) ? "Graphic" : objname; if(ObjectFind(0,objname)>=0) res=graphic.Attach(0,objname); else res=graphic.Create(0,objname,0,65,45,(int)(0.6*width),(int)(0.65*height)); if(!res) return(NULL); //--- add curves graphic.CurveAdd(function1,from,to,step,type); graphic.CurveAdd(function2,from,to,step,type); //--- plot curves graphic.CurvePlotAll(); graphic.Update(); //--- return resource name return graphic.ChartObjectName(); } //+------------------------------------------------------------------+ //| Create graphic of three curve and return resource name | //+------------------------------------------------------------------+ string GraphPlot(CurveFunction function1,CurveFunction function2,CurveFunction function3,const double from,const double to,const double step,ENUM_CURVE_TYPE type=CURVE_POINTS,string objname=NULL) { CGraphic graphic; ulong width = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); ulong height= ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); //--- create graphic bool res=false; objname = (objname==NULL) ? "Graphic" : objname; if(ObjectFind(0,objname)>=0) res=graphic.Attach(0,objname); else res=graphic.Create(0,objname,0,65,45,(int)(0.6*width),(int)(0.65*height)); if(!res) return(NULL); //--- add curves graphic.CurveAdd(function1,from,to,step,type); graphic.CurveAdd(function2,from,to,step,type); graphic.CurveAdd(function3,from,to,step,type); //--- plot curves graphic.CurvePlotAll(); graphic.Update(); //--- return resource name return graphic.ChartObjectName(); } //+------------------------------------------------------------------+