Custom indicators and infographics in CCanvas

Contents

Introduction

In our previous article we considered the principles of constructing graphical indicators using the methods for developing simple primitives of the CCanvas class. However, the custom graphics library has much broader capabilities, therefore I suggest to have a look at new types of indicators with more complex structural implementation. In addition, we are going to plot pseudo-3D indicator types and dynamic infographics.

CLineRounded class

I am not going to recreate the general structure of basic classes in this article in order to implement graphical objects. Instead, we will use the ready-made CustomGUI library described in the previous article. In particular, the CCanvasBase class is to be used as a base one. The newly developed classes are to complement the list in the CustomGUI.mqh file.

To develop a simple linear indicator, we should define its structure and basic elements. The Fig. 1 presents the elements you can manage when using this indicator type. Note that they are not simple elements.

Fig. 1. The basic structure of a simple linear indicator

The element implemented by the CCanvas class methods is considered to be simple (basic). For example, only the Value is considered to be simple in the linear indicator since it is implemented using the CCanvas::TextOut() method. The three remaining elements are similar and consist mainly of three basic figures — two filled circles (CCanvas::FillCircle() implementation) and a rectangle (CCanvas::FillRectangle()).

Create the LineRounded.mqh file in the CustomGUI/Indicators folder, create the СLineRounded class in the newly generated file and assign the previously created CCanvasBase class as a base one for it.

The full list of properties and methods of the СLineRounded class can be studied in the CustomGUI/Indicators/LineRounded.mqh file. Let's focus on the methods for developing and setting the indicator and updating its values. As mentioned above, the indicator is to consist of composite elements. The implementation of these elements is commented on in separate blocks in the listing below.

As you can see, the Frame and Backdrop are implemented using the two methods. Do not forget that these objects are layers and are drawn overlapping each other. Therefore, first, we draw the frame followed by the smaller backdrop, indicator scale and numerical value.

As we can see, the backdrop implementation block is present again at the beginning of the method. Why? Keep in mind the layer-by-layer drawing of the elements by means of consistent application of the corresponding methods. In other words, first, we display the scale background followed by the indicator with its length defined by the maximum parameter value. When the new indicator value arrives, the backdrop layer is re-drawn first followed by the scale with a new length.

Creating and passing the value to the indicator is implemented in a very simple manner. In the listing below, you can see the two indicators with small settings differing only in that one of them has a maximum value two times greater than that of another one.

The Fig. 2 clearly shows that the indicator scale length has an appropriate value in case of similar values and different scales. The value of 50 and maximum (100 for the first and 200 for the second one) are selected so that the display result can be evaluated visually.

Fig. 2. Sample rounded linear indicator

CHexagon class

We can use a number of methods to plot an indicator in the form of a regular hexagon using the primitives set by the CCanvas class. They include construction of a polyline with subsequent filling in the area and "assembling" six equilateral triangles, like slices of pizza. However, our objective is the maximum simplicity. Therefore, we are going to construct a regular hexagon using three primitives — a rectangle and two isosceles triangles.

Fig. 3. A regular hexagon structure

The right hexagon is inserted in the square canvas. Keep in mind the figure properties:

The side of the regular hexagon is equal to the radius of the circle circumscribed around it (in our case, this is the half of the canvas side). This feature is necessary when plotting a rectangle.

The hexagon angle is 120 degrees, therefore the angles at the bases of isosceles triangles are 30 degrees each. This data is necessary for defining the triangle height and finding the coordinates of the triangles base points when using the CCanvas::FillTriangle() method.

The basic structure of the indicator itself is quite simple and, in addition to the hexagon, includes two text objects - numerical value and description (Fig. 4).

Fig. 4. The basic structure of the hexagonal indicator

Create the Hexagon.mqh file in the CustomGUI/Indicators folder, create the СHexagon class in the newly generated file and assign the previously created CCanvasBase class as a base one for it. Include it to the general list:

In the Create() method, the value of the isosceles triangles is assigned to a variable. In fact, in this way we find the coordinates of the triangle points along the ordinate (Y) axis. The method of transferring and updating the numerical value is different only in the fact that the text object responsible for drawing a numerical value receives the value argument:

The result is displayed in Fig. 5. This basic template is very easy to configure and change.

Fig. 5. Sample implementation of the indicator set using the CHexagon class

CPetal class

The implementation of the petal-shaped indicator requires 2-3 primitives from the CCanvas class of methods. These are the filled circle (the FillCircle() method) and, depending on the form, 1-2 filled triangles (FillTriangle()). The structure and set of elements are shown in Fig. 6.

Fig. 6. The basic structure of the petal indicator

As we can see, two triangles are used here but we are going to include several form types to the class using the 'enum' enumeration. Let's consider these types in more detail:

TOPRIGHT — consists of a circle and triangle with its visible vertex directed to the upper right corner.

TOPLEFT — consists of a circle and triangle with its visible vertex directed to the upper left corner.

BOTTOMRIGHT — consists of a circle and triangle with its visible vertex directed to the lower right corner.

BOTTOMLEFT — consists of a circle and triangle with its visible vertex directed to the lower left corner.

BOTHRIGHT — consists of a circle and two triangles. The upper triangle is located in the upper right corner.

BOTHLEFT— consists of a circle and two triangles. The upper triangle is located in the upper left corner.

Fig. 7. Petal indicator form types

Let's start implementation. Create the Petal.mqh file in the CustomGUI/Indicators folder, create the СPetal class in the newly generated file and assign the previously created CCanvasBase class as a base one for it. Also, include it to the common list that now looks as follows:

We will not dwell on the standard properties. Let's consider the methods of creating an indicator and updating its values. In the Create() method, after the construction of the filled circle, filled triangles are drawn in the specified positions using the ENUM_POSITION enumeration depending on the previously considered "form type" property:

CHistogram class

The histogram class is based on the CLIneGraph class, or more precisely — the general structure of constructing the coordinate axes, axis scales and their values. Therefore, there is no need to describe this stage. Let's dwell in more details on the types of histograms and the implementation using the CCanvas class primitives. Before moving on to the implementation of the histogram indicator, let's define the form types.

enum ENUM_TYPE_HISTOGRAM
{
SIMPLE=1,
TRIANGLE=2,
RECTANGLE=3
};

SIMPLE — a simple form is based on the triangle-shaped histogram (Fig.10) with its height fixed as a numerical value on the chart.

Create the Histogram.mqh file in the CustomGUI/Indicators folder, create the СHistogram class in the newly generated file and assign the previously created CCanvasBase class as a base one for it. Also, include it to the common list in the CustomGUI.mqh file. Most class methods and properties are similar to the CLineGraph class, including the Create() method. Therefore, let's have a look at the fundamental differences only, namely the SetArrayValue() method.

The fundamental difference is that the ENUM_TYPE_HISTOGRAM histogram type described above is considered in the histogram plotting block by the specified data array. The method of visual display of three RSI indicators with different periods has been implemented as a usage example.

Fig. 13. Result of the indicator in the form of a histogram of three RSI periods

CPyramid class

We have examined the classes and principles of constructing complex shapes using primitives. While describing the class for constructing histogram-type indicators, I have mentioned plotting pseudo-3D objects (Fig. 13) by means of color selection. However, the pyramid is not a flat figure. Therefore, we have to use its isometric projection in a given two-dimensional coordinate system. The basic structure does not contain too many elements (Fig.14), but the method of the pyramid projection and visualization is the main part of the class implementation.

Fig. 14. Basic structure of the CPyramid class

Create the Pyramid.mqh file in the CustomGUI/Indicators folder, create the СPyramid class in the newly generated file and assign the previously created CCanvasBase class as a base one for it. Also, include it to the common list in the CustomGUI.mqh file. Now, the general list of included classes looks as follows:

You can find the full list of properties and methods in the class itself. Let's focus on the key ones. Before considering the basic Create() and NewValue() methods, we will dwell on the private methods used in it.

The Equation() method is used to find the two-point straight-line equation. In particular, it defines the k and b ratios for the general equation y = kx + b from the conventional two-point straight-line equation:

This method is used to further define the straight-line equations by specified points to find the crossing points of the AB and AC pyramid edges and straight lines parallel to the pyramid's base lines. The coordinates of the points shown in Fig. 15 are necessary for constructing triangles similar to the side faces of the pyramid. In turn, they are sections of our indicator.

Build the left side of the pyramid. Define A and B points coordinates and use them to find the straight-line equation.

Then, find the straight-line equations parallel to the pyramid base sides and the point of their crossing with the AB edge consequently in the cycle.

Use the obtained points to build sections and scale marks (divisions).

Construct the right side of the pyramid in a similar way.

Apart from sections and scale marks, add the scale values on the right side.

Vertical separation of two sections.

The method of setting and updating data features the two arguments: the current passed and maximum values. The essence of the method: Define the threshold values based on the maximum set value. When passing them, each section changes its color. When exceeding the threshold value, the section receives a specified color. When the value is crossed downwards, the section receives the color set as inactive.

Despite the more complex implementation of the indicator's rendering, its creation, setup and application are not more difficult as compared to the previous ones. Let's apply it for displaying standard ADX values as a small example. Depending on the indicator location, add the circular indicator in the upper left for comparison and visibility.

As we can see in the Fig. 16, the circular indicator displays the value above the third threshold of 30, therefore, three sections are colored at the current maximum value, which in this case is set to 50.

Fig. 16. Using a pyramid-shaped indicator

Conclusion

Implementation of the CCanvas-based classes proves that the library capabilities are quite extensive in terms of graphics. Types and ways of displaying this type of indicators are limited only by imagination. The creation and arrangement of such indicators in the form of a library of include classes does not require special knowledge or effort.

The attached archive contains all the files applied in the article, which are located in the appropriate folders. For correct operation, place the MQL5 folder to the terminal's root directory from the archive.

This article discusses the implementation of various methods of time filtering a cross-platform expert advisor. The time filter classes are responsible for checking whether or not a given time falls under a certain time configuration setting.

This article considers creation of documentation for MQL5 code starting with the automated markup of required tags. It also provides the description of how to use the Doxygen software, how to properly configure it and how to receive results in different formats, including html, HtmlHelp and PDF.

The Graphic.mqh library has been designed to work with graphics in MQL5. The article provides an example of its practical application and explains the idea of sorting. The general concept of sorting is described here since each type of sorting already has at least one separate article, while some of sorting types are objects of detailed studies.