4.7.1 Chart Custom Draw

Every study can plot a custom drawing in a chart window. This is possible using the IChartCustomDrawRegistrator interface that is available through the ChartCustomDraw property.

This interface contains methods for registering/unregistering a custom drawer, the initiation of the drawing of the entire chart window and a property for accessing the data that is required during the drawing. It is possible to register/unregister the custom drawer from any thread. Re-plotting initiation is also available from any thread and will be started asynchronously in the main thread, i.e. not as soon the method is called.

Custom drawer is an object that implements the IChartCustomDrawer interface with the only one void Draw(DrawContext context, EDrawPhases phase) method. This method will be called several times within one process of chart window plotting, once per each phase of plotting. The plotting process is performed on a phased basis:

  1. background is filled,
  2. grid is plotted,
  3. background figures are plotted (rectangles, ellipses, etc)
  4. bar series is plotted, the chart for an instrument itself
  5. foreground figures are plotted (trend lines, Fibonacci levels, etc)

The current phase of plotting can be checked in the phase argument. It allows plotting at the required moment, for example, either above or below the bar series, at the background, or in front of all the objects of the chart.

The first argument of the IChartCustomDrawer.Draw() method context is a wrapper class that contains all the necessary data and means for the plotting, they are:

  • public readonly Color BackGround; - chart background color.
  • public RectangleF DirtyRect; - Custom drawer can require to re-plot a bigger space than is currently being plotted and can notify the caller about that by setting the required space in this property. If on exiting from the IChartCustomDrawer.Draw() method this space is bigger than the one set in DrawRect, then the caller will initiate the plotting procedure on all phases one more time. This double plotting allows the receipt all the required information about the objects that need to be plotted in a bigger space, thus it is being re-plotted without any visual artifacts (flashing).
  • public readonly RectangleF DrawRect; - contains the space that is required to be re-plotted. To speed up the plotting process, the whole chart window does not need to be re-plotted, only the space where the indicated objects were changed. For example, the last bar has been updated in real time, so in this case only a little space containing this bar should be re-plotted and the DrawRect property will contain this space.
  • public readonly IDrawDataEnviroment Environment; - this interface gives access to the data on the charts bars and status line. Also it contains the methods for conversion of the coordinates from one type to another. For example:
  1. from bar number/index to screen coordinate X
  2. from the point, date-time, price to screen coordinate point
  • public readonly bool FinalDraw; - returns TRUE when the IChartCustomDrawer.Draw() method will not be called within the current plotting and phase, regardless of the values of the DirtyRect and ReDraw fields. If nothing is currently being plotted the custom drawing will not be indicated on the chart (at least for 1 fps).
  • public readonly RectangleF FullRect; - contains the whole chart space where the plotting is possible. Basically, this is the whole internal space of a chart window.
  • public readonly Graphics graphics; -plotting is performed by means of GDI/GDI+ with System.Drawing.Graphics. graphics class, this is a reference to the object of this type. All the plots are created by calling methods of this class. More information about methods and properties of System.Drawing.Graphics class can be found on msdn.
  • public bool ReDraw; -should be set as TRUE if the whole chart window should be re-plotted.

NOTE: A pre-built indicator _Market_Depth_on_Chart_2_ uses custom drawings and can be used as an example.