forked from nique_372/GrapichsByLeo
541 lines
35 KiB
MQL5
541 lines
35 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Grid.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_MQH_BY_LEO
|
|
#define GRAPHICS_HISTOGRAM_EJE_EJES_MQH_BY_LEO
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
#include "..\\..\\PartInf\\ParteInf.mqh"
|
|
#include "..\\..\\General\\TextoCanvas.mqh"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
const string DoubleToStrPrefixArrFormats[5] = {"%.*f", "%.*f K", "%.*f M", "%.*f B", "%.*f T"};
|
|
//+------------------------------------------------------------------+
|
|
string DoubleToStrPrefix(double value, int8_t decimals)
|
|
{
|
|
const double abs_val = MathAbs(value);
|
|
int idx = 0;
|
|
double v = value;
|
|
|
|
if(abs_val >= 1000000000000.0)
|
|
{
|
|
v /= 1000000000000.0;
|
|
idx = 4;
|
|
}
|
|
else
|
|
if(abs_val >= 1000000000.0)
|
|
{
|
|
v /= 1000000000.0;
|
|
idx = 3;
|
|
}
|
|
else
|
|
if(abs_val >= 1000000.0)
|
|
{
|
|
v /= 1000000.0;
|
|
idx = 2;
|
|
}
|
|
else
|
|
if(abs_val >= 1000.0)
|
|
{
|
|
v /= 1000.0;
|
|
idx = 1;
|
|
}
|
|
return StringFormat(DoubleToStrPrefixArrFormats[idx], decimals, v);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
struct HistogramEjeLineSection
|
|
{
|
|
double value;
|
|
string str_val;
|
|
int init; // X - Y
|
|
int c1; // Y1 -X1
|
|
int c2; // Y2 - X2
|
|
|
|
int c_text;
|
|
};
|
|
|
|
//--- EJe de X
|
|
struct HistogramEjeLineBasic
|
|
{
|
|
int init;
|
|
int c1;
|
|
int c2;
|
|
uint clr;
|
|
};
|
|
|
|
//---
|
|
|
|
|
|
//--- Eje Y con multiples secciones
|
|
// Obligtorios
|
|
#define HIST_EJE_FLAG_INIT_GENERAL 1
|
|
#define HIST_EJE_FLAG_INIT_LINE 2
|
|
|
|
|
|
// General
|
|
#define HIST_EJE_FLAG_INIT_TITULO 4
|
|
|
|
/*
|
|
X1
|
|
Y1
|
|
*/
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
typedef string(*HistFunctionFormatDouble)(double value, int8_t decimals);
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
class CHistogramEjeLine
|
|
{
|
|
protected:
|
|
uint m_init_flags;
|
|
CCanvasCustom* m_canvas;
|
|
|
|
uint m_clr_clean;
|
|
|
|
//---
|
|
CTextCanvas* m_titulo; // Titulo del eje
|
|
int m_titulo_gap_px; // Gap respecto al titulok
|
|
|
|
//--- Linea general
|
|
int m_x;
|
|
int m_y;
|
|
int m_c2; // Cordanada 2
|
|
int m_size_line_sections;
|
|
uint m_clr;
|
|
|
|
//--- Secciones
|
|
int m_secciones_size;
|
|
HistogramEjeLineSection m_secciones[];
|
|
int m_section_size_px; // Tamaño en picxlex
|
|
int m_section_size_gap_value; // Gap entre la linea y el texto
|
|
int m_sections_font_size;
|
|
string m_sections_font;
|
|
|
|
uint m_sections_alingment;
|
|
int8_t m_sections_decimals;
|
|
HistFunctionFormatDouble m_function_val_to_str;
|
|
|
|
//--- Valores
|
|
double m_max_value;
|
|
double m_min_value;
|
|
double m_change_value;
|
|
|
|
// 0 se ubica a la izquierda lineas a oiuiqer, 1 se ubica a la derecha lineas a la derecha
|
|
int m_mode_line;
|
|
bool m_use_change_value;
|
|
|
|
|
|
//---
|
|
virtual void TituloActulize() = 0;
|
|
virtual void RecalculeAndDrawSections() = 0;
|
|
virtual void RedrawSections() = 0;
|
|
virtual void OnNewFunctionFormat() = 0;
|
|
virtual void OnInitialize() = 0;
|
|
|
|
public:
|
|
CHistogramEjeLine();
|
|
~CHistogramEjeLine();
|
|
|
|
//--- Inicializa la clase (clr = linevertial tamibne las lines de las sessionces y texto de cada seccion)
|
|
void Init(CCanvasCustom* c, int x, int y, int size_line, uint clr_line_and_text_line, int mode);
|
|
void CreateSections(int inital_sections, double max_value, double min_value, bool use_change_val, double change_value,
|
|
int section_gap_value, int sections_size_px, int8_t decimals, int fontsize = 0, string font = NULL);
|
|
virtual void CreateTitulo(const string &txt, uint clr, int gap_titulo, int fontsize = 0, string font = NULL, uint flagtext = UINT_MAX) = 0;
|
|
|
|
//--- Limpa los pixles ocupados por la linea dejee, secciones y texto de cada sesion (menos el titulo), solo linmepa pxieles, no cambia el valores
|
|
virtual void CleanPixelsSections() = 0;
|
|
|
|
//--- Secciones
|
|
//- Funcion de formateo
|
|
void SectionsFormatStrFunction(HistFunctionFormatDouble new_function, bool redraw = false);
|
|
__forceinline HistFunctionFormatDouble SectionsFormatStrFunction() const { return m_function_val_to_str; }
|
|
|
|
//- Tamaño de cada "line" de valor
|
|
void SectionsUniqueSizeInPixels(int new_value, bool redraw = false);
|
|
__forceinline int SectionsUniqueSizeInPixels() const { return m_section_size_px; }
|
|
|
|
//- Fontsize de los textos de la linea del eje
|
|
void SectionsFontSize(int new_value, bool redraw = false);
|
|
__forceinline int SectionsFontSize() const { return m_sections_font_size;}
|
|
|
|
//- Font de los textos de la linea de eje
|
|
void SectionsFont(const string& new_value, bool redraw = false);
|
|
__forceinline string SectionsFont() const { return m_sections_font;}
|
|
|
|
//- Numero de seccions de la linea del eje
|
|
void SectionsSize(int new_value, bool redraw = false);
|
|
__forceinline int SectionsSize() const { return m_secciones_size; }
|
|
|
|
//- COlor de (lineas de sccion + texto de linea de seccion + line general)
|
|
void SectionsColor(uint new_clr, bool redraw = false);
|
|
__forceinline uint SectionsColor() const { return m_clr; }
|
|
|
|
//- Maximo de la linea del eje
|
|
void Max(double max, bool redraw = false);
|
|
__forceinline double Max() const { return m_max_value; }
|
|
|
|
//- Minimo de la linea del eje
|
|
void Min(double min, bool redraw = false);
|
|
__forceinline double Min() const { return m_min_value; }
|
|
|
|
//- Valor de cambio
|
|
void ChangeValue(double new_value, bool redraw = false);
|
|
__forceinline double ChangeValue() const { return m_change_value; }
|
|
__forceinline bool ChangeValueEnable() const { return m_use_change_value; }
|
|
|
|
//- Setear max, min, y chanbge_value opcional
|
|
void SetNewValues(double max, double min, double change_value, bool redraw = false);
|
|
|
|
|
|
//--- Cordenadas y tamaño
|
|
//- X
|
|
virtual void X(int new_value, bool redraw = false) = 0;
|
|
__forceinline int X() const { return m_x; }
|
|
|
|
//- Y
|
|
virtual void Y(int new_value, bool redraw = false) = 0;
|
|
__forceinline int Y() const { return m_y; }
|
|
|
|
//- LineSize
|
|
virtual void LineSize(int new_value, bool redraw = false) = 0;
|
|
__forceinline int LineSize() const { return m_size_line_sections; }
|
|
|
|
//- Set cordenadas
|
|
virtual void SetCordinates(int x, int y, int line_size, bool redraw = false) = 0;
|
|
|
|
//---
|
|
__forceinline int ModeLine() const { return m_mode_line; }
|
|
|
|
//---
|
|
void CleanColor(uint new_value) { m_clr_clean = new_value;}
|
|
__forceinline uint CleanColor() const { return m_clr_clean; }
|
|
|
|
|
|
//---
|
|
CTextCanvas* TituloGetPointer() { return m_titulo;}
|
|
};
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Macros |
|
|
//+------------------------------------------------------------------+
|
|
#define HIST_EJE_IS_INIT_GENERAL ((m_init_flags&HIST_EJE_FLAG_INIT_GENERAL) != 0)
|
|
#define HIST_EJE_IS_INIT_SECTIONS ((m_init_flags&HIST_EJE_FLAG_INIT_LINE) != 0)
|
|
#define HIST_EJE_IS_INIT_TITULO ((m_init_flags&HIST_EJE_FLAG_INIT_TITULO) != 0)
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
CHistogramEjeLine::CHistogramEjeLine()
|
|
: m_init_flags(0), m_titulo(NULL), m_canvas(NULL), m_use_change_value(false)
|
|
{
|
|
ArrayResize(m_secciones, 0);
|
|
m_function_val_to_str = DoubleToStrPrefix; // Funcion por defecto
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
CHistogramEjeLine::~CHistogramEjeLine()
|
|
{
|
|
if(CheckPointer(m_titulo) == POINTER_DYNAMIC)
|
|
{
|
|
delete m_titulo;
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CHistogramEjeLine::Init(CCanvasCustom* c, int x, int y, int size_line, uint clr_line_and_text_line, int mode)
|
|
{
|
|
if(HIST_EJE_IS_INIT_GENERAL)
|
|
return;
|
|
|
|
//---
|
|
m_canvas = c;
|
|
m_init_flags |= HIST_EJE_FLAG_INIT_GENERAL;
|
|
m_size_line_sections = size_line;
|
|
m_x = x;
|
|
m_y = y;
|
|
|
|
m_clr = clr_line_and_text_line;
|
|
m_mode_line = mode;
|
|
|
|
//--- Seteamos alingement
|
|
OnInitialize();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CHistogramEjeLine::CreateSections(int inital_sections, double max_value, double min_value, bool use_change_val, double change_value,
|
|
int section_gap_value, int sections_size_px, int8_t decimals, int fontsize = 0, string font = NULL)
|
|
{
|
|
if(HIST_EJE_IS_INIT_SECTIONS)
|
|
return;
|
|
/*
|
|
Como siempre si el fontsize es 0 o font es null, se usa el de canvas, asi que si el usuario ya tiene en fontseteado en canvas (usa el de la clase CHistogram)
|
|
, peude dejar los parametros como esta, pero si quiere un font o fontsize cusotm para los ejes le da un valor
|
|
*/
|
|
//---
|
|
int is = inital_sections;
|
|
is += 1; // Agregamos el maximo
|
|
is += 1; // Agregamos al minimo
|
|
is += int(use_change_val); // Si use es true=1, se le sumara 1
|
|
|
|
//---
|
|
m_init_flags |= HIST_EJE_FLAG_INIT_LINE;
|
|
m_max_value = max_value;
|
|
m_min_value = min_value;
|
|
m_change_value = change_value;
|
|
m_sections_font = font != NULL ? font : m_canvas.FontNameGet();
|
|
m_sections_font_size = fontsize > 0 ? fontsize : m_canvas.FontSizeGet();
|
|
m_section_size_gap_value = section_gap_value;
|
|
|
|
m_sections_decimals = decimals;
|
|
m_use_change_value = use_change_val;
|
|
m_section_size_px = sections_size_px;
|
|
m_secciones_size = is;
|
|
ArrayResize(m_secciones, m_secciones_size);
|
|
|
|
//---
|
|
if(!use_change_val)
|
|
m_change_value = DBL_MAX; // Lo ponemos a un valor invalido
|
|
|
|
//---
|
|
RecalculeAndDrawSections();
|
|
|
|
//---
|
|
// int xmin = m_section_size_gap_value + m_sections_font_size;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CHistogramEjeLine::ChangeValue(double new_value, bool redraw = false)
|
|
{
|
|
//---
|
|
if(!m_use_change_value)
|
|
return;
|
|
|
|
//---
|
|
CleanPixelsSections();
|
|
|
|
//---
|
|
m_change_value = new_value;
|
|
|
|
|
|
//--- Dibujamos las secciones
|
|
RecalculeAndDrawSections(); // Secciones-Line
|
|
|
|
//---
|
|
if(redraw)
|
|
m_canvas.Update();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CHistogramEjeLine::Min(double min, bool redraw = false)
|
|
{
|
|
//---
|
|
CleanPixelsSections();
|
|
|
|
//---
|
|
m_min_value = min;
|
|
|
|
//--- Dibujamos las secciones
|
|
RecalculeAndDrawSections(); // Secciones-Line
|
|
|
|
//---
|
|
if(redraw)
|
|
m_canvas.Update();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CHistogramEjeLine::Max(double max, bool redraw = false)
|
|
{
|
|
//---
|
|
CleanPixelsSections();
|
|
|
|
//---
|
|
m_max_value = max;
|
|
|
|
//--- Dibujamos las secciones
|
|
RecalculeAndDrawSections(); // Secciones-Line
|
|
|
|
//---
|
|
if(redraw)
|
|
m_canvas.Update();
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CHistogramEjeLine::SetNewValues(double max, double min, double change_value, bool redraw = false)
|
|
{
|
|
//---
|
|
CleanPixelsSections();
|
|
|
|
//---
|
|
m_min_value = min;
|
|
m_max_value = max;
|
|
m_change_value = change_value;
|
|
|
|
//--- Dibujamos las secciones
|
|
RecalculeAndDrawSections(); // Secciones-Line
|
|
|
|
//---
|
|
if(redraw)
|
|
m_canvas.Update();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CHistogramEjeLine::SectionsColor(uint new_clr, bool redraw = false)
|
|
{
|
|
//---
|
|
m_clr = new_clr;
|
|
|
|
//---
|
|
RedrawSections();
|
|
|
|
//---
|
|
if(redraw)
|
|
m_canvas.Update();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CHistogramEjeLine::SectionsSize(int new_value, bool redraw = false)
|
|
{
|
|
//---
|
|
if(new_value < 0)
|
|
return;
|
|
|
|
//---
|
|
int nv = new_value + 2 + int(m_use_change_value); // se le suma 2 del minimo y el maximo, ademas de 1 si es que se usa change_value
|
|
|
|
//---
|
|
CleanPixelsSections();
|
|
|
|
//---
|
|
m_secciones_size = nv;
|
|
ArrayResize(m_secciones, m_secciones_size);
|
|
|
|
//--- Dibujamos las secciones
|
|
RecalculeAndDrawSections(); // Secciones-Line
|
|
|
|
//---
|
|
if(redraw)
|
|
m_canvas.Update();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CHistogramEjeLine::SectionsFont(const string &new_value, bool redraw = false)
|
|
{
|
|
//---
|
|
CleanPixelsSections(); // Limpieza previa
|
|
|
|
//---
|
|
m_sections_font = new_value;
|
|
|
|
//--- Dibujamos las secciones
|
|
RecalculeAndDrawSections(); // Secciones-Line
|
|
|
|
//---
|
|
if(redraw)
|
|
m_canvas.Update();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CHistogramEjeLine::SectionsFontSize(int new_value, bool redraw = false)
|
|
{
|
|
//---
|
|
CleanPixelsSections(); // Limpieza previa
|
|
|
|
//---
|
|
m_sections_font_size = new_value;
|
|
|
|
//--- Dibujamos las secciones
|
|
RecalculeAndDrawSections(); // Secciones-Line
|
|
// Cuidado un fontsize mas grande haria que el titulo se dezplaze myucho, hacinedo que posibledmne desapareza
|
|
TituloActulize();
|
|
|
|
//---
|
|
if(redraw)
|
|
m_canvas.Update();
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CHistogramEjeLine::SectionsUniqueSizeInPixels(int new_value, bool redraw = false)
|
|
{
|
|
//---
|
|
CleanPixelsSections(); // Limpieza previa
|
|
|
|
//---
|
|
m_section_size_px = new_value;
|
|
|
|
//--- Dibujamos las secciones
|
|
// Cuidado un ancho mas grande haria que el titulo se dezplaze myucho, hacinedo que posibledmne desapareza
|
|
RecalculeAndDrawSections(); // Secciones-Line
|
|
TituloActulize();
|
|
|
|
//---
|
|
if(redraw)
|
|
m_canvas.Update();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CHistogramEjeLine::SectionsFormatStrFunction(HistFunctionFormatDouble new_function, bool redraw = false)
|
|
{
|
|
//---
|
|
CleanPixelsSections();
|
|
|
|
//---
|
|
m_function_val_to_str = new_function;
|
|
|
|
//---
|
|
// Cuidado con el titulo un texto mas gradne podira hacer colisiones, esto se podria ajustar auto auqnue es mas responsabidliad del usuario
|
|
OnNewFunctionFormat();
|
|
|
|
//---
|
|
if(redraw)
|
|
m_canvas.Update();
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
//+------------------------------------------------------------------+
|