Скачать MetaTrader 5

У кого есть опыт использования CCanvas?

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Хочешь написать торгового робота? Загляни в Справочник MQL5!
Vasiliy Sokolov
21811
Vasiliy Sokolov 2016.09.27 16:36 

Собственно вопрос в сабже. Недавно заметил появление новой папки MQL5\Include\Canvas. В ней располагаются классы для работы с графикой. В документации по этим классам пока пусто. Особенно заинтересовали классы HistogramChart и LineChart. Пытался создать линейный график примерно таким образом:

#property copyright "Copyright 2016, Vasiliy Sokolov."
#property link      "http://www.mql5.com"
#property version   "1.00"
#include <Canvas\Charts\LineChart.mqh>
CLineChart lchart;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   double s1[18] = {1, 3, 2, 5, 4, 4, 5, 8, 7, 6, 5, 4, 3, 5, 4, 3, 2, 1};
   lchart.Create("MeMem", 400, 400);
   lchart.SeriesAdd(s1, "Test", clrRed);
   return(INIT_SUCCEEDED);
}

Ничего не вышло.

Без какой-либо документации исследовать сложно.

Разработчики или просто люди с опытом: приведите если нетрудно несколько примеров работы с этими классами. Какие возможности в них реализованы? Как быстро их заюзать? В общем колитесь знающие люди:)

MetaQuotes
Админ
24950
Renat Fatkhullin 2016.09.27 17:12  
Все есть в поиске: https://www.mql5.com/ru/search#!keyword=Canvas
Vladimir Karputov
Модератор
46246
Vladimir Karputov 2016.09.27 17:14  
Vasiliy Sokolov:

Собственно вопрос в сабже. Недавно заметил появление новой папки MQL5\Include\Canvas. В ней располагаются классы для работы с графикой. В документации по этим классам пока пусто. Особенно заинтересовали классы HistogramChart и LineChart. Пытался создать линейный график примерно таким образом:

Ничего не вышло.

Без какой-либо документации исследовать сложно.

Разработчики или просто люди с опытом: приведите если нетрудно несколько примеров работы с этими классами. Какие возможности в них реализованы? Как быстро их заюзать? В общем колитесь знающие люди:)

Примеры работы с построением графиков трёх типов: ...\MQL5\Scripts\Examples\Canvas\Charts\...
Anatoli Kazharski
56961
Anatoli Kazharski 2016.09.27 21:27  
Показывал пример использования с некоторыми доработками в рамках публикуемой библиотеки для создания графических интерфейсов: Графические интерфейсы IX: Элементы "Индикатор выполнения" и "Линейный график" (Глава 2)
Vasiliy Sokolov
21811
Vasiliy Sokolov 2016.09.28 10:10  
Всем спасибо! Особенно наличие примеров работы с чартами порадовало.
Vasiliy Sokolov
21811
Vasiliy Sokolov 2016.11.02 12:41  

Как оказалось ChartCanvas пока еще очень сырая библиотека. Ошибки сыплются как тараканы.

Вот первая: если попытаться построить линейный график (LineChart), содержащий больше точек для построения чем ширина окна в пикселях произойдет следующее:

 

 Такое происходит из-за особенностей работы алгоритма с округлением:

//+------------------------------------------------------------------+
//| Draws lines                                                      |
//+------------------------------------------------------------------+
void CLineChart::DrawData(const uint index)
  {
   double value=0.0;
//--- check
   CArrayDouble *data=m_values.At(index);
   if(data==NULL)
      return;
   int total=data.Total();
   if(total<=1)
      return;
//--- calculate
   int dx=m_data_area.Width()/(total-1);
   int x=m_data_area.left+1;
   int y1=0;
   int y2=(int)(m_y_0-data[0]*m_scale_y);
//--- draw
   for(int i=1;i<total;i++,x+=dx)
     {
      y1=y2;
      //x = (int)MathRound(per_dx*(i-1));
      //int dx=(int)MathRound(per_dx*i);
      double val=data[i];
      if(val==EMPTY_VALUE)
         continue;
      if(m_accumulative)
         value+=val;
      else
         value=val;
      y2=(int)(m_y_0-value*m_scale_y);
      if(m_filled)
        {
         ...
        }
      else
      {
         LineAA(x,y1,x+dx,y2,(uint)m_colors[index],STYLE_SOLID);
      }
     }
  }

dx в данном случае всегда будет равен нулю, если количество значений total больше ширины окна width. Итерация в этом случае не будет менять x и он всегда останется равным нулю.

Правильное решение следующее: необходимо прямо внутри цикла рассчитать значение предыдущей и текущей точек и построить линию между ними:

//+------------------------------------------------------------------+
//| Draws lines                                                      |
//+------------------------------------------------------------------+
void CPointsChart::DrawData(const uint index)
  {
   double value=0.0;
//--- check
   CArrayDouble *data=m_values.At(index);
   if(data==NULL)
      return;
   int total=data.Total();
   if(total<=1)
      return;
//--- calculate
   int dx=m_data_area.Width()/(total-1);
   double per_dx = ((double)m_data_area.Width())/(total-1);
   int x=m_data_area.left+1;
   int y1=0;
   int y2=(int)(m_y_0-data[0]*m_scale_y);
//--- draw
   for(int i=1;i<total;i++)
     {
      y1=y2;
      int px = m_data_area.left + 1 + (int)MathRound(per_dx*(i-1));
      x =      m_data_area.left + 1 + (int)MathRound(per_dx*i);
      double val=data[i];
      if(val==EMPTY_VALUE)
         continue;
      if(m_accumulative)
         value+=val;
      else
         value=val;
      y2=(int)(m_y_0-value*m_scale_y);
      if(m_filled)
        {
         ...
        }
      else
      {
         LineAA(px,y1,x,y2,(uint)m_colors[index],STYLE_SOLID);
      }
     }
  }

 В этом случае сработает автомасштабирование и график начнет отображаться верно:

 

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий