373 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			MQL5
		
	
	
	
	
	
			
		
		
	
	
			373 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			MQL5
		
	
	
	
	
	
//+------------------------------------------------------------------+
 | 
						|
//|                                                          Ver.mqh |
 | 
						|
//|                                  Copyright 2025, Niquel Mendoza. |
 | 
						|
//|                     https://www.mql5.com/es/users/nique_372/news |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
#property copyright "Copyright 2025, Niquel Mendoza."
 | 
						|
#property link      "https://www.mql5.com/es/users/nique_372/news"
 | 
						|
#property strict
 | 
						|
 | 
						|
#ifndef GRAPHICS_HISTOGRAM_EJE_EJES_VER_MQH_BY_LEO
 | 
						|
#define GRAPHICS_HISTOGRAM_EJE_EJES_VER_MQH_BY_LEO
 | 
						|
 | 
						|
#include "Ejes.mqh"
 | 
						|
 | 
						|
 | 
						|
#define HIST_LINE_MODE_ARRIBA 1
 | 
						|
#define HIST_LINE_MODE_ABAJO 0
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
class CHistogramEjeLineVertical : public CHistogramEjeLine
 | 
						|
 {
 | 
						|
protected:
 | 
						|
  void               TituloActulize() override;
 | 
						|
  void               RecalculeAndDrawSections() override;
 | 
						|
  void               RedrawSections() override;
 | 
						|
  void               OnNewFunctionFormat() override;
 | 
						|
  void               OnInitialize() override;
 | 
						|
 | 
						|
public:
 | 
						|
  void               CleanPixelsSections() override;
 | 
						|
  void               CreateTitulo(const string &txt, uint clr, int gap_titulo, int fontsize = 0, string font = NULL, uint flagtext = UINT_MAX) override;
 | 
						|
 | 
						|
  //--- Cordenadas y tamaño
 | 
						|
  //- X
 | 
						|
  void               X(int new_value, bool redraw = false) override;
 | 
						|
 | 
						|
  //- Y
 | 
						|
  void               Y(int new_value, bool redraw = false) override;
 | 
						|
 | 
						|
  //- LineSize
 | 
						|
  void               LineSize(int new_value, bool redraw = false) override;
 | 
						|
 | 
						|
  //
 | 
						|
  void               SetCordinates(int x, int y, int line_size, bool redraw = false) override;
 | 
						|
 };
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramEjeLineVertical::OnInitialize(void)
 | 
						|
 {
 | 
						|
  m_c2 = m_x + m_size_line_sections;
 | 
						|
 | 
						|
  if(m_mode_line == HIST_LINE_MODE_ARRIBA)
 | 
						|
    m_sections_alingment = TA_CENTER | TA_BOTTOM;
 | 
						|
  else // 0
 | 
						|
    m_sections_alingment = TA_CENTER | TA_TOP;
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramEjeLineVertical::LineSize(int new_value, bool redraw = false)
 | 
						|
 {
 | 
						|
//---
 | 
						|
  const bool reduce = new_value < m_size_line_sections;
 | 
						|
 | 
						|
//--- Limpiamos la linea
 | 
						|
  if(reduce) // SOlo limpiar si se reducio
 | 
						|
    CleanPixelsSections();
 | 
						|
 | 
						|
//---
 | 
						|
  m_size_line_sections = new_value;
 | 
						|
  m_c2 = m_x + new_value;
 | 
						|
 | 
						|
//--- Dibujamos las secciones
 | 
						|
  RecalculeAndDrawSections(); // Secciones-Line
 | 
						|
  TituloActulize(); // Titulo
 | 
						|
 | 
						|
//---
 | 
						|
  if(redraw)
 | 
						|
    m_canvas.Update();
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramEjeLineVertical::X(int new_value, bool redraw = false)
 | 
						|
 {
 | 
						|
//---
 | 
						|
  CleanPixelsSections();
 | 
						|
 | 
						|
//---
 | 
						|
  m_x = new_value;
 | 
						|
  m_c2 = m_x + m_size_line_sections;
 | 
						|
 | 
						|
//--- Dibujamos las secciones
 | 
						|
  RecalculeAndDrawSections(); // Secciones-Line
 | 
						|
  TituloActulize(); // Titulo
 | 
						|
 | 
						|
//---
 | 
						|
  if(redraw)
 | 
						|
    m_canvas.Update();
 | 
						|
 }
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramEjeLineVertical::Y(int new_value, bool redraw = false)
 | 
						|
 {
 | 
						|
//---
 | 
						|
  CleanPixelsSections();
 | 
						|
 | 
						|
//---
 | 
						|
  m_y = new_value;
 | 
						|
 | 
						|
//--- Dibujamos las secciones
 | 
						|
  RecalculeAndDrawSections(); // Secciones-Line
 | 
						|
  TituloActulize(); // Titulo
 | 
						|
 | 
						|
//---
 | 
						|
  if(redraw)
 | 
						|
    m_canvas.Update();
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramEjeLineVertical::SetCordinates(int x, int y, int line_size, bool redraw = false)
 | 
						|
 {
 | 
						|
//--- Limpiamos la linea
 | 
						|
  CleanPixelsSections();
 | 
						|
 | 
						|
//---
 | 
						|
  m_x = x;
 | 
						|
  m_y = y;
 | 
						|
  m_size_line_sections = line_size;
 | 
						|
  m_c2 = m_x + line_size;
 | 
						|
 | 
						|
//--- Dibujamos las secciones
 | 
						|
  RecalculeAndDrawSections(); // Secciones-Line
 | 
						|
  TituloActulize(); // Titulo
 | 
						|
 | 
						|
//---
 | 
						|
  if(redraw)
 | 
						|
    m_canvas.Update();
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramEjeLineVertical::CreateTitulo(const string &txt, uint clr, int gap_titulo, int fontsize = 0, string font = NULL, uint flagtext = UINT_MAX)
 | 
						|
 {
 | 
						|
  if(HIST_EJE_IS_INIT_TITULO)
 | 
						|
    return;
 | 
						|
 | 
						|
//  (1 = izquierda : 0 = derecha)
 | 
						|
  m_init_flags |= HIST_EJE_FLAG_INIT_TITULO;
 | 
						|
  m_titulo = new CTextCanvas();
 | 
						|
  if(m_mode_line == HIST_LINE_MODE_ARRIBA)
 | 
						|
   {
 | 
						|
    int y = m_y - m_section_size_px - m_section_size_gap_value - m_sections_font_size - m_titulo_gap_px;
 | 
						|
    int x = m_x + (m_size_line_sections >> 1);
 | 
						|
    m_titulo.Create(m_canvas, x, y, txt, clr, m_sections_alingment, fontsize, font, flagtext, 0);
 | 
						|
   }
 | 
						|
  else
 | 
						|
   {
 | 
						|
    int y = m_y + m_section_size_px + m_section_size_gap_value + m_sections_font_size + m_titulo_gap_px;
 | 
						|
    int x = m_x + (m_size_line_sections >> 1);
 | 
						|
    m_titulo.Create(m_canvas, x, y, txt, clr, m_sections_alingment, fontsize, font, flagtext, 0);
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramEjeLineVertical::TituloActulize()
 | 
						|
 {
 | 
						|
  if(!HIST_EJE_IS_INIT_TITULO)
 | 
						|
    return; // SI el titulo no esta seteado enotnces retornamos
 | 
						|
 | 
						|
  if(m_mode_line == HIST_LINE_MODE_ARRIBA)
 | 
						|
   {
 | 
						|
    int y = m_y - m_section_size_px - m_section_size_gap_value - m_sections_font_size - m_titulo_gap_px;
 | 
						|
    int x = m_x + (m_size_line_sections >> 1);
 | 
						|
    m_titulo.ChangeYAndX(x, y);
 | 
						|
   }
 | 
						|
  else
 | 
						|
   {
 | 
						|
    int y = m_y + m_section_size_px + m_section_size_gap_value + m_sections_font_size + m_titulo_gap_px;
 | 
						|
    int x = m_x + (m_size_line_sections >> 1);
 | 
						|
    m_titulo.ChangeYAndX(x, y);
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramEjeLineVertical::RecalculeAndDrawSections(void)
 | 
						|
 {
 | 
						|
//---
 | 
						|
  const double x_percentages_step = 1.00 / double(m_secciones_size - 1); // obtenemos el %decimal que le toca a cada seccion
 | 
						|
  double x_next_per = 0.00; // SIeuiguente porcenrge
 | 
						|
 | 
						|
  double v_step = (m_max_value - m_min_value) / double(m_secciones_size  - 1);
 | 
						|
  double v = m_min_value; // Siguiente valor
 | 
						|
 | 
						|
//---
 | 
						|
  m_canvas.LineHorizontal(m_x, m_c2, m_y, m_clr);
 | 
						|
 | 
						|
//--- Line horizontal  (1 = izquierda : 0 = derecha)
 | 
						|
  ::TextSetFont(m_sections_font, m_sections_font_size);
 | 
						|
 | 
						|
// De izquierda (menor valor) hacia derecha (mayor valor)
 | 
						|
  if(m_use_change_value)
 | 
						|
   {
 | 
						|
    const double range_min =  m_change_value - m_min_value;
 | 
						|
    const double corte_x_perce = range_min / (m_max_value - m_min_value);
 | 
						|
    const int x_corte = m_x + int(corte_x_perce * fabs(m_c2 - m_x)); // Cordenada de anclaje
 | 
						|
    // init = x
 | 
						|
    // c1 = y1
 | 
						|
    // c2 = y2
 | 
						|
 | 
						|
    bool c = false;
 | 
						|
    for(int i = 0; i < m_secciones_size; i++)
 | 
						|
     {
 | 
						|
      const int x = m_x + int(round(m_size_line_sections * x_next_per));
 | 
						|
 | 
						|
      //--- Valores de la seccion
 | 
						|
      if(!c && v >= m_change_value) // Si c es falso y se uspero el change value forzamos
 | 
						|
       {
 | 
						|
        m_secciones[i].value = m_change_value;
 | 
						|
        m_secciones[i].init = x_corte;
 | 
						|
        c = true;
 | 
						|
       }
 | 
						|
      else
 | 
						|
       {
 | 
						|
        m_secciones[i].value = v;
 | 
						|
        m_secciones[i].init = x;
 | 
						|
       }
 | 
						|
 | 
						|
   
 | 
						|
      m_secciones[i].str_val = m_function_val_to_str(m_secciones[i].value, m_sections_decimals);
 | 
						|
 | 
						|
      //--- Modo
 | 
						|
      // c_text = y_text
 | 
						|
      /*
 | 
						|
        y1 c1
 | 
						|
        |
 | 
						|
        |
 | 
						|
        |
 | 
						|
        |
 | 
						|
        y2 c2
 | 
						|
      */
 | 
						|
 | 
						|
      if(m_mode_line == HIST_LINE_MODE_ARRIBA)
 | 
						|
       {
 | 
						|
        m_secciones[i].c2 = m_y;
 | 
						|
        m_secciones[i].c1 = m_y - m_section_size_px;
 | 
						|
        m_secciones[i].c_text = m_secciones[i].c1 - m_section_size_gap_value;
 | 
						|
       }
 | 
						|
      else
 | 
						|
       {
 | 
						|
        m_secciones[i].c1 = m_y;
 | 
						|
        m_secciones[i].c2 = m_y + m_section_size_px;
 | 
						|
        m_secciones[i].c_text = m_secciones[i].c2 + m_section_size_gap_value;
 | 
						|
       }
 | 
						|
 | 
						|
      //--- Dibujamos
 | 
						|
      m_canvas.TextOuTF(m_secciones[i].init, m_secciones[i].c_text, m_secciones[i].str_val, m_clr, m_sections_alingment);
 | 
						|
      m_canvas.LineVertical(m_secciones[i].init, m_secciones[i].c1, m_secciones[i].c2, m_clr);
 | 
						|
 | 
						|
      //--- Next
 | 
						|
      x_next_per += x_percentages_step;
 | 
						|
      v += v_step;
 | 
						|
     }
 | 
						|
   }
 | 
						|
  else
 | 
						|
   {
 | 
						|
    // Duplicaremos el coidog pero la idera es maximoar optimizacion ahcer un terminarioc a cada iteracion talvez no sea lo mejor
 | 
						|
    for(int i = 0; i < m_secciones_size; i++)
 | 
						|
     {
 | 
						|
      const int x = m_x + int(round(m_size_line_sections * x_next_per));
 | 
						|
 | 
						|
      //--- Valores de la seccion
 | 
						|
      m_secciones[i].value =  v;
 | 
						|
      m_secciones[i].init = x;
 | 
						|
      m_secciones[i].str_val = m_function_val_to_str(m_secciones[i].value, m_sections_decimals);
 | 
						|
 | 
						|
      //--- Modo
 | 
						|
      if(m_mode_line == HIST_LINE_MODE_ARRIBA)
 | 
						|
       {
 | 
						|
        m_secciones[i].c2 = m_y;
 | 
						|
        m_secciones[i].c1 = m_y - m_section_size_px;
 | 
						|
        m_secciones[i].c_text = m_secciones[i].c1 - m_section_size_gap_value;
 | 
						|
       }
 | 
						|
      else
 | 
						|
       {
 | 
						|
        m_secciones[i].c1 = m_y;
 | 
						|
        m_secciones[i].c2 = m_y + m_section_size_px;
 | 
						|
        m_secciones[i].c_text = m_secciones[i].c2 + m_section_size_gap_value;
 | 
						|
       }
 | 
						|
 | 
						|
      //--- Dibujamos
 | 
						|
      m_canvas.TextOuTF(m_secciones[i].init, m_secciones[i].c_text, m_secciones[i].str_val, m_clr, m_sections_alingment);
 | 
						|
      m_canvas.LineVertical(m_secciones[i].init, m_secciones[i].c1, m_secciones[i].c2, m_clr);
 | 
						|
 | 
						|
      //--- Next
 | 
						|
      x_next_per += x_percentages_step;
 | 
						|
      v += v_step;
 | 
						|
     }
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramEjeLineVertical::RedrawSections(void)
 | 
						|
 {
 | 
						|
//---
 | 
						|
  m_canvas.LineHorizontal(m_x, m_c2, m_y, m_clr);
 | 
						|
 | 
						|
//--- Line horizontal  (1 = izquierda : 0 = derecha)
 | 
						|
  ::TextSetFont(m_sections_font, m_sections_font_size);
 | 
						|
 | 
						|
//---
 | 
						|
  for(int i = 0; i < m_secciones_size; i++)
 | 
						|
   {
 | 
						|
    m_canvas.TextOuTF(m_secciones[i].init, m_secciones[i].c_text, m_secciones[i].str_val, m_clr, m_sections_alingment);
 | 
						|
    m_canvas.LineVertical(m_secciones[i].init, m_secciones[i].c1, m_secciones[i].c2, m_clr);
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramEjeLineVertical::CleanPixelsSections(void)
 | 
						|
 {
 | 
						|
//---
 | 
						|
  m_canvas.LineHorizontal(m_x, m_c2, m_y, m_clr_clean);
 | 
						|
 | 
						|
//--- Line horizontal  (1 = izquierda : 0 = derecha)
 | 
						|
  ::TextSetFont(m_sections_font, m_sections_font_size);
 | 
						|
 | 
						|
//--- De abajo (menor valor) hacia arriba (mayor valor)
 | 
						|
  for(int i = 0; i < m_secciones_size; i++)
 | 
						|
   {
 | 
						|
    m_canvas.TextOuTF(m_secciones[i].init, m_secciones[i].c_text, m_secciones[i].str_val, m_clr_clean, m_sections_alingment);
 | 
						|
    m_canvas.LineVertical(m_secciones[i].init, m_secciones[i].c1, m_secciones[i].c2, m_clr_clean);
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramEjeLineVertical::OnNewFunctionFormat()
 | 
						|
 {
 | 
						|
//--- Line horizontal  (1 = izquierda : 0 = derecha)
 | 
						|
  ::TextSetFont(m_sections_font, m_sections_font_size);
 | 
						|
 | 
						|
//--- De abajo (menor valor) hacia arriba (mayor valor)
 | 
						|
  for(int i = 0; i < m_secciones_size; i++)
 | 
						|
   {
 | 
						|
    m_secciones[i].str_val = m_function_val_to_str(m_secciones[i].value, m_sections_decimals);
 | 
						|
    m_canvas.TextOuTF(m_secciones[i].init, m_secciones[i].c_text, m_secciones[i].str_val, m_clr, m_sections_alingment);
 | 
						|
    m_canvas.LineVertical(m_secciones[i].init, m_secciones[i].c1, m_secciones[i].c2, m_clr);
 | 
						|
   }
 | 
						|
 }
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
#endif 
 |