547 lines
		
	
	
	
		
			39 KiB
		
	
	
	
		
			MQL5
		
	
	
	
	
	
			
		
		
	
	
			547 lines
		
	
	
	
		
			39 KiB
		
	
	
	
		
			MQL5
		
	
	
	
	
	
//+------------------------------------------------------------------+
 | 
						|
//|                                                     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
 | 
						|
 | 
						|
#include "HistogramaBases.mqh"
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
#define HISTOGRAM_CALCULE_ANCHO(v,m) int((v)*(m))
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
class CHistogramVertical : public CHistogram
 | 
						|
 {
 | 
						|
private:
 | 
						|
  void               RecalculeCordinatesBarsAndText() override final;
 | 
						|
  void               OnNeweCordinatesBarsAndSize() override final;
 | 
						|
  void               OnBarraAdd(int index) override final;
 | 
						|
  void               OnBarrDelete(double extra_value) override final;
 | 
						|
  void               OnSetLienzo() override final;
 | 
						|
  void               OnMaxOrMinValueSuperate() override final;
 | 
						|
  void               InitCordinates() override final;
 | 
						|
  void               ConjuntoBarWidth(int index, double new_value) override final;
 | 
						|
 | 
						|
public:
 | 
						|
                     CHistogramVertical()  { m_type = HISTOGRAM_VERTICAL; }
 | 
						|
 | 
						|
  int                AddConjuntoBar(const string &label, uint label_clr, int label_fontsize, const string &label_font, ENUM_HISTOGRAM_TEXT_MODE label_mode, int barras_de_reserva_, int eje_gap,
 | 
						|
                                    ENUM_HIST_DRAW_RECT_STYLE initial_style, double width = 0.000000) override final;
 | 
						|
  using              CHistogram::AddConjuntoBar; // Desocultamos la funcion soibrecatgada de AddCounjtoBar con clr aleatorio
 | 
						|
 | 
						|
  void               MinConjuntoAncho(int new_value)  override;
 | 
						|
  void               CreateEjeLine(int mode_position_line_sections, uint clr_line_Sections, uint clr_line_fixed, int initial_sections,
 | 
						|
                                   int section_gap_value, int sections_size_px, int8_t section_decimals, int section_fontsize = 0, string section_font = NULL) override;
 | 
						|
 | 
						|
  void               NumConjuntoBars(int num_bars, int reserve_bars = 0) override;
 | 
						|
  using              CHistogram::NumConjuntoBars; // Descoultamos el meotodo getter
 | 
						|
 };
 | 
						|
 
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Resize al numero de barras                                       |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
// Unicamente resize el tamaño de berras
 | 
						|
// Para poder setear las barras use SetBar con redraw false (todavia no se le asigna cordenadas)
 | 
						|
// O tambien SetBarFast
 | 
						|
void CHistogramVertical::NumConjuntoBars(int num_bars, int reserve_bars = 0) 
 | 
						|
 {
 | 
						|
  m_bars_size = num_bars;
 | 
						|
  ArrayResize(m_bars, m_bars_size);
 | 
						|
  for(int i = 0; i < m_bars_size; i++)
 | 
						|
   {
 | 
						|
    m_bars[i] = new CHistogramConjuntoVertical();
 | 
						|
    m_bars[i].ReserveBarras(reserve_bars);
 | 
						|
    m_bars[i].CleanColor(m_back_color);
 | 
						|
   }
 | 
						|
  m_curr_index_bar_p = 0;
 | 
						|
 }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramVertical::CreateEjeLine(int mode_position_line_sections, uint clr_line_Sections, uint clr_line_fixed, int initial_sections,
 | 
						|
                                       int section_gap_value, int sections_size_px, int8_t section_decimals, int section_fontsize = 0, string section_font = NULL)
 | 
						|
 {
 | 
						|
// Apunta a algo, es seguro comprar con NULL, dado que al eliminar o iniciar el puntero tendra un valor de NULL (no hay objeto invalido, pero direccion seigue apuntado a algo)
 | 
						|
  if(m_eje != NULL)
 | 
						|
    return;
 | 
						|
  m_eje = new CHistogramEjeVertical();
 | 
						|
  int x2 = m_barras_x1 + m_barras_espacio_dibujable_width;
 | 
						|
  int y2 = m_barras_y1 + m_barras_espacio_dibujable_height;
 | 
						|
  m_eje.Init(m_canvas, m_barras_x1, x2, m_barras_y1, y2, mode_position_line_sections, clr_line_Sections, clr_line_fixed, m_back_color);
 | 
						|
  const bool use_change_val = (m_fr_change_value == m_fr_min_value) ? false : true;
 | 
						|
  m_eje.HistogramLinePointerGet().CreateSections(initial_sections, m_fr_max_value, m_fr_min_value, use_change_val, m_fr_change_value, section_gap_value, sections_size_px,
 | 
						|
      section_decimals, section_fontsize, section_font);  // Solo crea seccion el titulo lo hace el usuario si es que desea
 | 
						|
 }
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramVertical::MinConjuntoAncho(int new_value)
 | 
						|
 {
 | 
						|
//---
 | 
						|
  m_barras_min_width = new_value;
 | 
						|
 | 
						|
//--- Verificamos si las barras cumple, si no la marcamos para su posterior eliminacion
 | 
						|
  int idx_to_Remove[];
 | 
						|
  double extra = 0.00;
 | 
						|
 | 
						|
  for(int i = 0; i < m_bars_size; i++)
 | 
						|
   {
 | 
						|
    m_bars[i].CleanBarras(false);
 | 
						|
    m_bars[i].TextClean();
 | 
						|
    const double v = m_bars[i].ValueForAncho();
 | 
						|
 | 
						|
    //  Calcular con max_height (vertical)
 | 
						|
    const int a = HISTOGRAM_CALCULE_ANCHO(v, m_barras_max_height);
 | 
						|
 | 
						|
    if(a < m_barras_min_width)
 | 
						|
     {
 | 
						|
      extra += v;
 | 
						|
      idx_to_Remove.Push(i);
 | 
						|
     }
 | 
						|
   }
 | 
						|
 | 
						|
//--- Eliminar conjuntos muy pequeños
 | 
						|
  const int size_remove = ArraySize(idx_to_Remove);
 | 
						|
  if(size_remove > 0)
 | 
						|
   {
 | 
						|
    for(int i = 0; i < size_remove; i++)
 | 
						|
     {
 | 
						|
      const int k = idx_to_Remove[i];
 | 
						|
      m_bars[k].Destroy();
 | 
						|
      delete m_bars[k];
 | 
						|
     }
 | 
						|
 | 
						|
    RemoveMultipleIndexes(m_bars, idx_to_Remove, 0);
 | 
						|
    m_bars_size -= size_remove;
 | 
						|
   }
 | 
						|
  else
 | 
						|
   {
 | 
						|
    return; // Todas las barras cumple, nada que hacer
 | 
						|
   }
 | 
						|
 | 
						|
//--- Redistribuir espacio extra
 | 
						|
  const double rest = extra / double(m_bars_size);
 | 
						|
 | 
						|
//  Iterar en Y (vertical)
 | 
						|
  int y = m_barras_cordinate_init;
 | 
						|
 | 
						|
// gap_corte es distancia entre x1 y condernada de corte
 | 
						|
  const int gap_corte = m_barras_cordenanda_eje_corte - m_barras_x1;
 | 
						|
 | 
						|
  for(int i = 0; i < m_bars_size; i++)
 | 
						|
   {
 | 
						|
    m_bars[i].ValueForAnchoAument(rest);
 | 
						|
 | 
						|
    //  Calcular alto con max_height
 | 
						|
    const int a = HISTOGRAM_CALCULE_ANCHO(m_bars[i].ValueForAncho(), m_barras_max_height);
 | 
						|
 | 
						|
    //  Parámetros correctos para vertical
 | 
						|
    m_bars[i].SetNewsCordenadasAndSize(m_barras_x1, y, a);
 | 
						|
 | 
						|
    //  Avanzar en Y
 | 
						|
    y += a + m_barras_espacio_entre;
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Añade un nuevo conjunto de barras                                |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
int CHistogramVertical::AddConjuntoBar(const string &label, uint label_clr, int label_fontsize, const string &label_font, ENUM_HISTOGRAM_TEXT_MODE label_mode, int barras_de_reserva_, int eje_gap,
 | 
						|
                                       ENUM_HIST_DRAW_RECT_STYLE initial_style, double width = 0.000000)
 | 
						|
 {
 | 
						|
  m_curr_index_bar_p = m_bars_size;
 | 
						|
  ArrayResize(m_bars, m_bars_size + 1);
 | 
						|
  m_bars[m_bars_size] = new CHistogramConjuntoVertical(); // Cambiar esto, talvez com template.. <>
 | 
						|
  m_bars[m_bars_size].ReserveBarras(barras_de_reserva_);
 | 
						|
  m_bars[m_bars_size].Set(m_canvas, label, label_clr, label_mode, label_fontsize, label_font, eje_gap, initial_style);
 | 
						|
  m_bars[m_bars_size].ValueForAncho(width);
 | 
						|
  m_bars[m_bars_size].CleanColor(m_back_color); // Color de limpeiza que sea el fondo del lienzo
 | 
						|
  m_bars_size++;
 | 
						|
  return m_curr_index_bar_p;
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramVertical::InitCordinates(void)
 | 
						|
 {
 | 
						|
// Posición Y inicial (ya incluye gap_init)
 | 
						|
  int y = m_barras_cordinate_init;
 | 
						|
 | 
						|
// gap_corte es distancia entre x1 y condernada de corte
 | 
						|
  const int gap_corte = m_barras_cordenanda_eje_corte - m_barras_x1;
 | 
						|
 | 
						|
// Iterar sobre cada conjunto de barras
 | 
						|
  for(int i = 0; i < m_bars_size; i++)
 | 
						|
   {
 | 
						|
    // Calcular alto del conjunto basado en su proporción
 | 
						|
    // ValueForAncho() retorna proporción (0.0-1.0)
 | 
						|
    // m_barras_max_height es el espacio vertical total disponible
 | 
						|
    const int a = HISTOGRAM_CALCULE_ANCHO(m_bars[i].ValueForAncho(), m_barras_max_height);
 | 
						|
 | 
						|
    // Inicializar conjunto con sus coordenadas
 | 
						|
    m_bars[i].Init(
 | 
						|
      m_function_value_to_pixel,                   // Función conversión valor→pixel
 | 
						|
      m_barras_x1,                                 // X1: borde izquierdo del área
 | 
						|
      y,                                           // Y: posición vertical actual
 | 
						|
      gap_corte,                                   //Gap del corte (pos↔neg)
 | 
						|
      a,                                           // Alto del conjunto en pixeles
 | 
						|
      m_factor_conversion_value_to_pixel_pos,     // Factor para valores positivos
 | 
						|
      m_factor_conversion_value_to_pixel_neg,     // Factor para valores negativos
 | 
						|
      m_fr_change_value                            // Valor donde ocurre el corte
 | 
						|
    );
 | 
						|
 | 
						|
    // Avanzar a la siguiente posición Y
 | 
						|
    // = posición actual + alto del conjunto + espacio entre conjuntos
 | 
						|
    y += a + m_barras_espacio_entre;
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Configura el lienzo (VERTICAL)                                   |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramVertical::OnSetLienzo(void)
 | 
						|
 {
 | 
						|
//  En vertical, los conjuntos se distribuyen en ALTURA (eje Y)
 | 
						|
  m_barras_max_height = m_barras_espacio_dibujable_height;
 | 
						|
  m_barras_max_height -= (m_bars_size - 1) * m_barras_espacio_entre;  // Restamos gaps entre conjuntos
 | 
						|
  m_barras_max_height -= (m_barras_gap_init + m_barras_gap_end);      // Restamos gaps inicial y final
 | 
						|
 | 
						|
// Las barras dentro de cada conjunto crecen en ANCHO (eje X)
 | 
						|
  m_barras_max_width = m_barras_espacio_dibujable_width;
 | 
						|
 | 
						|
//--- Calcular proporciones default para conjuntos sin ancho especificado
 | 
						|
  int idx_no_tiene[];
 | 
						|
  double sum = 0.00;
 | 
						|
 | 
						|
  for(int i = 0; i < m_bars_size; i++)
 | 
						|
   {
 | 
						|
    const double v = m_bars[i].ValueForAncho();
 | 
						|
    if(v == 0.00)
 | 
						|
      idx_no_tiene.Push(i);
 | 
						|
    else
 | 
						|
      sum += v;
 | 
						|
   }
 | 
						|
 | 
						|
//--- Tamaño del array
 | 
						|
  const int s = ArraySize(idx_no_tiene);
 | 
						|
 | 
						|
//--- No hay defaults, todos tienen proporción definida
 | 
						|
  if(s < 1)
 | 
						|
    return;
 | 
						|
 | 
						|
//--- Calcular y asignar proporción default
 | 
						|
  const double def_factor = (1.0 - sum) / double(s);
 | 
						|
  for(int i = 0; i < s; i++)
 | 
						|
    m_bars[idx_no_tiene[i]].ValueForAncho(def_factor);
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramVertical::RecalculeCordinatesBarsAndText(void)
 | 
						|
 {
 | 
						|
  for(int i = 0; i < m_bars_size; i++)
 | 
						|
    m_bars[i].RecalculeCordinates();
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramVertical::OnMaxOrMinValueSuperate(void)
 | 
						|
 {
 | 
						|
// gap_corte es distancia entre x1 y condernada de corte
 | 
						|
  const int gap_corte = m_barras_cordenanda_eje_corte - m_barras_x1;
 | 
						|
 | 
						|
  for(int i = 0; i < m_bars_size; i++)
 | 
						|
   {
 | 
						|
    m_bars[i].SetNewsValues(gap_corte,
 | 
						|
                            m_factor_conversion_value_to_pixel_pos,
 | 
						|
                            m_factor_conversion_value_to_pixel_neg,
 | 
						|
                            m_fr_change_value);
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Recalcula coordenadas y tamaños (VERTICAL)                       |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramVertical::OnNeweCordinatesBarsAndSize(void)
 | 
						|
 {
 | 
						|
//  Iterar en Y (vertical), no en X
 | 
						|
  int y = m_barras_cordinate_init;
 | 
						|
 | 
						|
  for(int i = 0; i < m_bars_size; i++)
 | 
						|
   {
 | 
						|
    //  Calcular ALTO usando max_height
 | 
						|
    const int a = HISTOGRAM_CALCULE_ANCHO(m_bars[i].ValueForAncho(), m_barras_max_height);
 | 
						|
 | 
						|
    //  Parámetros correctos (x_fijo, y_variable, alto)
 | 
						|
    m_bars[i].SetNewsCordenadasAndSize(m_barras_x1, y, a);
 | 
						|
 | 
						|
    //  Avanzar en Y
 | 
						|
    y += a + m_barras_espacio_entre;
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Se ejecuta al añadir un conjunto (VERTICAL)                      |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramVertical::OnBarraAdd(int index)
 | 
						|
 {
 | 
						|
//  Restar espacio de HEIGHT (no width)
 | 
						|
  m_barras_max_height -= m_barras_espacio_entre;
 | 
						|
 | 
						|
  double extra = m_bars[index].ValueForAncho();
 | 
						|
 | 
						|
  if(extra == 0.00)
 | 
						|
   {
 | 
						|
    extra = 1.0 / double(m_bars_size);
 | 
						|
   }
 | 
						|
 | 
						|
  double rest = extra / double(m_bars_size - 1);
 | 
						|
 | 
						|
//--- Reducir proporción de otros conjuntos
 | 
						|
  int idx_to_Remove[];
 | 
						|
  extra = 0.00;
 | 
						|
 | 
						|
  for(int i = 0; i < m_bars_size; i++)
 | 
						|
   {
 | 
						|
    m_bars[i].CleanBarras(false);
 | 
						|
    m_bars[i].TextClean();
 | 
						|
 | 
						|
    if(i == index)
 | 
						|
      continue;
 | 
						|
 | 
						|
    m_bars[i].ValueForAnchoReduce(rest);
 | 
						|
    const double v = m_bars[i].ValueForAncho();
 | 
						|
 | 
						|
    //  Calcular con max_height
 | 
						|
    const int a = HISTOGRAM_CALCULE_ANCHO(v, m_barras_max_height);
 | 
						|
 | 
						|
    if(a < m_barras_min_width)
 | 
						|
     {
 | 
						|
      extra += v;
 | 
						|
      idx_to_Remove.Push(i);
 | 
						|
     }
 | 
						|
   }
 | 
						|
 | 
						|
//--- Eliminar conjuntos muy pequeños
 | 
						|
  const int size_remove = ArraySize(idx_to_Remove);
 | 
						|
  if(size_remove > 0)
 | 
						|
   {
 | 
						|
    for(int i = 0; i < size_remove; i++)
 | 
						|
     {
 | 
						|
      const int k = idx_to_Remove[i];
 | 
						|
      m_bars[k].Destroy();
 | 
						|
      delete m_bars[k];
 | 
						|
     }
 | 
						|
 | 
						|
    RemoveMultipleIndexes(m_bars, idx_to_Remove, 0);
 | 
						|
    m_bars_size -= size_remove;
 | 
						|
   }
 | 
						|
 | 
						|
//--- Redistribuir espacio extra
 | 
						|
  rest = extra / double(m_bars_size);
 | 
						|
 | 
						|
//  Iterar en Y
 | 
						|
  int y = m_barras_cordinate_init;
 | 
						|
 | 
						|
//  gap_corte es X absoluto
 | 
						|
  const int gap_corte = m_barras_cordenanda_eje_corte - m_barras_x1;
 | 
						|
 | 
						|
  for(int i = 0; i < m_bars_size; i++)
 | 
						|
   {
 | 
						|
    m_bars[i].ValueForAnchoAument(rest);
 | 
						|
 | 
						|
    //  Calcular alto con max_height
 | 
						|
    const int a = HISTOGRAM_CALCULE_ANCHO(m_bars[i].ValueForAncho(), m_barras_max_height);
 | 
						|
 | 
						|
    if(i == index)
 | 
						|
     {
 | 
						|
      //  Init con parámetros correctos
 | 
						|
      m_bars[i].Init(m_function_value_to_pixel,
 | 
						|
                     m_barras_x1,    //  X fijo
 | 
						|
                     y,              //  Y variable
 | 
						|
                     gap_corte,      //  X de corte
 | 
						|
                     a,              //  Alto
 | 
						|
                     m_factor_conversion_value_to_pixel_pos,
 | 
						|
                     m_factor_conversion_value_to_pixel_neg,
 | 
						|
                     m_fr_change_value);
 | 
						|
     }
 | 
						|
    else
 | 
						|
     {
 | 
						|
      //  SetNewsCordenadasAndSize con parámetros correctos
 | 
						|
      m_bars[i].SetNewsCordenadasAndSize(m_barras_x1, y, a);
 | 
						|
     }
 | 
						|
 | 
						|
    //  Avanzar en Y
 | 
						|
    y += a + m_barras_espacio_entre;
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Maneja eliminación de conjunto (VERTICAL)                        |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramVertical::OnBarrDelete(double extra_value)
 | 
						|
 {
 | 
						|
// La limpieza ya se hace en la clase base
 | 
						|
 | 
						|
// Distribuir el espacio liberado entre conjuntos restantes
 | 
						|
  const double rest = extra_value / double(m_bars_size);
 | 
						|
 | 
						|
// Iterar en Y (vertical), no en X
 | 
						|
  int y = m_barras_cordinate_init;  //   Posición Y inicial
 | 
						|
 | 
						|
// gap_corte es distancia entre x1 y condernada de corte
 | 
						|
  const int gap_corte = m_barras_cordenanda_eje_corte - m_barras_x1;
 | 
						|
 | 
						|
  for(int i = 0; i < m_bars_size; i++)
 | 
						|
   {
 | 
						|
    // Aumentar proporción del conjunto
 | 
						|
    m_bars[i].ValueForAnchoAument(rest);
 | 
						|
 | 
						|
    // Calcular ALTO (no ancho) usando max_height
 | 
						|
    const int a = HISTOGRAM_CALCULE_ANCHO(m_bars[i].ValueForAncho(), m_barras_max_height);
 | 
						|
 | 
						|
    // SetNewsCordenadasAndSize con parámetros correctos
 | 
						|
    // Para vertical: (x_fijo, y_variable, alto)
 | 
						|
    m_bars[i].SetNewsCordenadasAndSize(m_barras_x1, y, a);
 | 
						|
 | 
						|
    //    Avanzar en Y (no en X)
 | 
						|
    y += a + m_barras_espacio_entre;
 | 
						|
   }
 | 
						|
 }
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Cambia el ancho/alto de un conjunto (VERTICAL)                   |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CHistogramVertical::ConjuntoBarWidth(int index, double new_value)
 | 
						|
 {
 | 
						|
  double extra = new_value - m_bars[index].ValueForAncho();
 | 
						|
  m_bars[index].ValueForAncho(new_value);
 | 
						|
 | 
						|
  if(m_bars_size <= 1)
 | 
						|
   {
 | 
						|
    LogWarning("No se puede cambiar ancho con solo 1 grupo", FUNCION_ACTUAL);
 | 
						|
    return;
 | 
						|
   }
 | 
						|
 | 
						|
//--- Si extra > 0: Se aumentó el tamaño del conjunto 'index'
 | 
						|
  if(extra > 0.00)
 | 
						|
   {
 | 
						|
    double rest = extra / double(m_bars_size - 1);
 | 
						|
 | 
						|
    //--- Reducir proporción de los demás conjuntos
 | 
						|
    int idx_to_Remove[];
 | 
						|
    extra = 0.00;
 | 
						|
 | 
						|
    for(int i = 0; i < m_bars_size; i++)
 | 
						|
     {
 | 
						|
      m_bars[i].CleanBarras(false);
 | 
						|
      m_bars[i].TextClean();
 | 
						|
 | 
						|
      if(i != index)
 | 
						|
        m_bars[i].ValueForAnchoReduce(rest);
 | 
						|
 | 
						|
      const double v = m_bars[i].ValueForAncho();
 | 
						|
 | 
						|
      //  Calcular con max_height (vertical)
 | 
						|
      const int a = HISTOGRAM_CALCULE_ANCHO(v, m_barras_max_height);
 | 
						|
 | 
						|
      if(a < m_barras_min_width)
 | 
						|
       {
 | 
						|
        extra += v;
 | 
						|
        idx_to_Remove.Push(i);
 | 
						|
       }
 | 
						|
     }
 | 
						|
 | 
						|
    //--- Eliminar conjuntos muy pequeños
 | 
						|
    const int size_remove = ArraySize(idx_to_Remove);
 | 
						|
    if(size_remove > 0)
 | 
						|
     {
 | 
						|
      for(int i = 0; i < size_remove; i++)
 | 
						|
       {
 | 
						|
        const int k = idx_to_Remove[i];
 | 
						|
        m_bars[k].Destroy();
 | 
						|
        delete m_bars[k];
 | 
						|
       }
 | 
						|
 | 
						|
      RemoveMultipleIndexes(m_bars, idx_to_Remove, 0);
 | 
						|
      m_bars_size -= size_remove;
 | 
						|
     }
 | 
						|
 | 
						|
    //--- Redistribuir espacio extra
 | 
						|
    rest = extra / double(m_bars_size);
 | 
						|
 | 
						|
    //  Iterar en Y (vertical)
 | 
						|
    int y = m_barras_cordinate_init;
 | 
						|
 | 
						|
    // gap_corte es distancia entre x1 y condernada de corte
 | 
						|
    const int gap_corte = m_barras_cordenanda_eje_corte - m_barras_x1;
 | 
						|
 | 
						|
    for(int i = 0; i < m_bars_size; i++)
 | 
						|
     {
 | 
						|
      m_bars[i].ValueForAnchoAument(rest);
 | 
						|
 | 
						|
      //  Calcular alto con max_height
 | 
						|
      const int a = HISTOGRAM_CALCULE_ANCHO(m_bars[i].ValueForAncho(), m_barras_max_height);
 | 
						|
 | 
						|
      //  Parámetros correctos para vertical
 | 
						|
      m_bars[i].SetNewsCordenadasAndSize(m_barras_x1, y, a);
 | 
						|
 | 
						|
      //  Avanzar en Y
 | 
						|
      y += a + m_barras_espacio_entre;
 | 
						|
     }
 | 
						|
   }
 | 
						|
  else
 | 
						|
   {
 | 
						|
    //--- Si extra < 0: Se redujo el tamaño del conjunto 'index'
 | 
						|
    extra *= -1.0;
 | 
						|
 | 
						|
    const double rest = extra / double(m_bars_size - 1);
 | 
						|
 | 
						|
    //  Iterar en Y
 | 
						|
    int y = m_barras_cordinate_init;
 | 
						|
 | 
						|
    // gap_corte es distancia entre x1 y condernada de corte
 | 
						|
    const int gap_corte = m_barras_cordenanda_eje_corte - m_barras_x1;
 | 
						|
 | 
						|
    //--- Limpiar todos los conjuntos
 | 
						|
    for(int i = 0; i < m_bars_size; i++)
 | 
						|
     {
 | 
						|
      m_bars[i].CleanBarras(false);
 | 
						|
      m_bars[i].TextClean();
 | 
						|
     }
 | 
						|
 | 
						|
    //--- Redibujar con nuevas proporciones
 | 
						|
    for(int i = 0; i < m_bars_size; i++)
 | 
						|
     {
 | 
						|
      if(i != index)
 | 
						|
        m_bars[i].ValueForAnchoAument(rest);
 | 
						|
 | 
						|
      //  Calcular alto con max_height
 | 
						|
      const int a = HISTOGRAM_CALCULE_ANCHO(m_bars[i].ValueForAncho(), m_barras_max_height);
 | 
						|
 | 
						|
      //  Parámetros correctos
 | 
						|
      m_bars[i].SetNewsCordenadasAndSize(m_barras_x1, y, a);
 | 
						|
 | 
						|
      //  Avanzar en Y
 | 
						|
      y += a + m_barras_espacio_entre;
 | 
						|
     }
 | 
						|
   }
 | 
						|
 }
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
#undef HISTOGRAM_CALCULE_ANCHO
 | 
						|
//+------------------------------------------------------------------+
 |