GrapichsByLeo/Histogram/Eje/Ver.mqh
2025-10-14 10:58:09 -05:00

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