//+------------------------------------------------------------------+ //| Vertical.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 HISTOGRAM_BARRA_VERTICAL_BY_LEO_MQH #define HISTOGRAM_BARRA_VERTICAL_BY_LEO_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include "Base.mqh" /* Estructura de la barra: --------- X ------------- | | IY1 | IX1 | | x1 x2 | y1 y1 | ___________ ________ | | Y | FNeg C Fpos | |___________ _______| | x1 x2 | y2 y2 | | | //--- IX1 = x1 inicial = m_barras_x1_init IY1 = y1 inicial = m_barras_y1_init FPos: valors positivos FNeg: valores negativos C: Corte */ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CHistogramConjuntoVertical : public CHistogramConjuntoNor { private: // CHistogramConjuntoVertical(void); // ~CHistogramConjuntoVertical(void); void OnNewValuesPosNegCorte(void) override; void RecalculeBarCordinates() override; void OnBarrasResize() override; void ResizeBarra(HistogramBar& barra) override; void CalculeTextCordinates() override final; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CHistogramConjuntoVertical::CalculeTextCordinates() { int x2 = m_barras_x1_init - m_label_gap_by_eje; int x1 = fmax(0, x2 - m_label.font_size + 1); m_label_function(x1, // X1 (fmax para prevenir bugs) x2, // X2 (SE LE RESTA EL GAP ) m_barras_y1_init, // Y1 (m_barras_y1_init + m_barras_ancho_total), //Y2 m_label.x, m_label.y); ::TextSetFont(m_label.font, m_label.font_size); m_canvas.TextOuTF(m_label.x, m_label.y, m_label.value, m_label.clr, m_label.mode); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CHistogramConjuntoVertical::ResizeBarra(HistogramBar &barra) { const int prev_h = barra.x2 - barra.x1; // Si este valor es pos entonces la barra es positiva const int h = HISTOGRAM_CONJ_VALUE_TO_PIXEL(barra.value); // Calculaos el width de la barra if(h < 0 && prev_h >= 0) //nuevo neg, anteior pos barra.x1 -= 2; // Reduce las cordenas else if(h >= 0 && prev_h < 0) //nuevo pos, anteior neg barra.x1 += 2; // aumenta barra.x2 = barra.x1 + h; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CHistogramConjuntoVertical::OnBarrasResize() { int y = m_barras_y1_init; for(int i = 0; i < m_barras_size; i++) { m_barras[i].y1 = y; y += m_barras_ancho_unico; m_barras[i].y2 = y; m_function_draw_rect(m_canvas, m_barras[i].x1, m_barras[i].y1, m_barras[i].x2, m_barras[i].y2, m_barras[i].clr); y += 1; // Siente inicio } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CHistogramConjuntoVertical::RecalculeBarCordinates() { //--- int y = m_barras_y1_init; const int x = (m_barras_x1_init + m_barras_gap_eje) + 1; // caluloamso para positivo por defecto int new_x = 0; for(int i = 0; i < m_barras_size; i++) { const int h = HISTOGRAM_CONJ_VALUE_TO_PIXEL(m_barras[i].value); // Calculaos el width de la barra //--- new_x = x; if(h < 0) new_x -= 2;// COnvertimos para negativo //--- m_barras[i].y1 = y; y += m_barras_ancho_unico; m_barras[i].y2 = y; m_barras[i].x1 = new_x; m_barras[i].x2 = new_x + h; m_function_draw_rect(m_canvas, m_barras[i].x1, m_barras[i].y1, m_barras[i].x2, m_barras[i].y2, m_barras[i].clr); y += 1; // Siente inicio } } //+------------------------------------------------------------------+ void CHistogramConjuntoVertical::OnNewValuesPosNegCorte(void) { int y = m_barras_y1_init; const int x = (m_barras_x1_init + m_barras_gap_eje) + 1; // caluloamso para positivo por defecto int new_x = 0; for(int i = 0; i < m_barras_size; i++) { const int prev_h = m_barras[i].x2 - m_barras[i].x1; // Si este valor es pos entonces la barra es positiva const int h = HISTOGRAM_CONJ_VALUE_TO_PIXEL(m_barras[i].value); // Calculaos el width de la barra // const bool pos = prev_h >= 0 && h >= 0; //--- new_x = x; if(h < 0) new_x -= 2; // COnvertimos para negativo // Caso1: Cambio de posicion limpiamos; pos a neg // Caso2: Cambio de posicion limpiamos: neg a pos // Caso3: Valor positivo, pero width menor // Caso4: Valor negativo, pero width menor //--- Clean //PrintFormat("[%d] prev h = %d | h = %d", i, prev_h, h); // if((prev_h > 0 && h < 0) || (prev_h < 0 && h > 0) || (pos && prev_h > h) || (!pos && h > prev_h)) // Limpiamos // m_function_draw_rect(m_canvas, m_barras[i].x1, m_barras[i].y1, m_barras[i].x2, m_barras[i].y2, m_clean_color); m_barras[i].y1 = y; y += m_barras_ancho_unico; m_barras[i].y2 = y; m_barras[i].x1 = new_x; m_barras[i].x2 = new_x + h; m_function_draw_rect(m_canvas, m_barras[i].x1, m_barras[i].y1, m_barras[i].x2, m_barras[i].y2, m_barras[i].clr); y += 1; // Siente inicio } } //+------------------------------------------------------------------+ #endif //+------------------------------------------------------------------+