//+------------------------------------------------------------------+ //| Histogram.mqh | //| Copyright 2018, DNG® | //| http://www.mql5.com/en/users/dng | //+------------------------------------------------------------------+ #property copyright "Copyright 2018, DNG®" #property link "http://www.mql5.com/en/users/dng" #property version "1.00" //--- #include "PlotBase.mqh" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_HISTOGRAM_ORIENTATION { HISTOGRAM_VERTICAL, //Markert Profile HISTOGRAM_HORIZONTAL //Classic }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CHistogram : public CPlotBase { private: ENUM_HISTOGRAM_ORIENTATION e_orientation; uint i_cells; public: CHistogram(); ~CHistogram(); //--- bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int size, ENUM_HISTOGRAM_ORIENTATION orientation=HISTOGRAM_HORIZONTAL); bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2, ENUM_HISTOGRAM_ORIENTATION orientation=HISTOGRAM_HORIZONTAL); int AddTimeserie(const double ×erie[]); bool UpdateTimeserie(const double ×erie[],uint timeserie=0); bool SetCells(uint value) { if(i_cells<=1) return (false); i_cells=value; return (true);} protected: // virtual void HistogramPlot(CCurve *curve); bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[], double &maxv,double &minv); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CHistogram::CHistogram() : e_orientation(HISTOGRAM_HORIZONTAL), i_cells(10) { } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CHistogram::~CHistogram() { } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CHistogram::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int size,ENUM_HISTOGRAM_ORIENTATION orientation=1) { int x2=x1+size; int y2=y1+size; return Create(chart,name,subwin,x1,y1,x2,y2,orientation); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CHistogram::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2,ENUM_HISTOGRAM_ORIENTATION orientation=1) { e_orientation=orientation; if(!CGraphic::Create(chart,name,subwin,x1,y1,x2,y2)) return false; m_chart_id=chart; m_subwin=subwin; return true; } //+------------------------------------------------------------------+ //| Calculate frequencies for data set | //+------------------------------------------------------------------+ bool CHistogram::CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[], double &maxv,double &minv) { int size=ArraySize(data); if(size<(int)i_cells*10) return (false); minv=data[ArrayMinimum(data)]; maxv=data[ArrayMaximum(data)]; double range=maxv-minv; double width=range/i_cells; if(width==0) return false; ArrayResize(intervals,i_cells); ArrayResize(frequency,i_cells); //--- set the interval centers for(uint i=0; i=i_cells) ind=i_cells-1; frequency[ind]++; } //--- normalize frequencies into percentage for(uint i=0; i=m_arr_curves.Total()) return false; if(ArraySize(timeserie)==0) return false; //--- CCurve *curve=m_arr_curves.At(timeserie_number); if(CheckPointer(curve)==POINTER_INVALID) return false; //--- curve.Update(timeserie); //--- return true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // CHistogram::HistogramPlot(CCurve *curve) // { // double data[],intervals[],frequency[]; // double max_value, min_value; // curve.GetY(data); // if(!CalculateHistogramArray(data,intervals,frequency,max_value,min_value)) // return; // //--- historgram parametrs // int histogram_width=fmax(curve.HistogramWidth(),2); // //--- check // if(ArraySize(frequency)==0 || ArraySize(intervals)==0) // return; // //--- // switch(e_orientation) // { // case HISTOGRAM_HORIZONTAL: // m_y.AutoScale(false); // m_x.Min(intervals[ArrayMinimum(intervals)]); // m_x.Max(intervals[ArrayMaximum(intervals)]); // m_x.MaxLabels(3); // m_x.ValuesFormat("%.0f"); // m_y.Min(0); // m_y.Max(frequency[ArrayMaximum(frequency)]); // m_y.ValuesFormat("%.2f"); // break; // case HISTOGRAM_VERTICAL: // m_x.AutoScale(false); // m_y.Min(intervals[ArrayMinimum(intervals)]); // m_y.Max(intervals[ArrayMaximum(intervals)]); // m_y.MaxLabels(3); // m_y.ValuesFormat("%.0f"); // m_x.Min(0); // m_x.Max(frequency[ArrayMaximum(frequency)]); // m_x.ValuesFormat("%.2f"); // break; // } // //--- // CalculateXAxis(); // CalculateYAxis(); // //--- calculate original of y // int originalY=m_height-m_down; // int originalX=m_width-m_right; // int yc0=ScaleY(0.0); // int xc0=ScaleX(0.0); // //--- gets curve color // uint clr=curve.Color(); // //--- draw // for(uint i=0; iyc0 && yc0>0) ? yc0 : originalY; // //--- // if(yc1>yc2) // yc2++; // else // yc2--; // //--- // m_canvas.FillRectangle(xc1,yc1,xc2,yc2,clr); // } // else // { // int yc=ScaleY(intervals[i]); // int xc=ScaleX(frequency[i]); // int yc1 = yc - histogram_width/2; // int yc2 = yc + histogram_width/2; // int xc1 = xc; // int xc2 = (originalX>xc0 && xc0>0) ? xc0 : originalX; // //--- // if(xc1>xc2) // xc2++; // else // xc2--; // //--- // m_canvas.FillRectangle(xc1,yc1,xc2,yc2,clr); // } // } // //--- // } //+------------------------------------------------------------------+