Click or drag to resize

Graphic renderer of indicators

Some indicators require a special drawing style, for example, two lines for the BollingerBands indicator. Or points for the Fractalsindicator. In this case, a graphical indicator renderer must be explicitly specified in ChartIndicatorElement

C#
var chartIndicatorElement = new ChartIndicatorElement()
{
    IndicatorPainter = new BollingerBandsPainter(),
};

Consider how to create your own IndicatorPainter on the example of the Fractals indicator.

All IndicatorPainter must be inherited from the BaseChartIndicatorPainter base class or the IChartIndicatorPainter interface:

C#
/// <summary>
/// The chart element for <see cref="Fractals"/>.
/// </summary>
[Indicator(typeof(Fractals))]
public class FractalsPainter : BaseChartIndicatorPainter
{
...
}

Set ChartLineElement chart elements that will represent upper and lower fractals:

C#
/// <summary>
/// The chart element for <see cref="Fractals"/>.
/// </summary>
[Indicator(typeof(Fractals))]
public class FractalsPainter : BaseChartIndicatorPainter
{
    /// <summary>
    /// <see cref="Fractals.Up"/> dots color.
    /// </summary>
    [Display(
        ResourceType = typeof(LocalizedStrings),
        Name = LocalizedStrings.Str2035Key,
        Description = LocalizedStrings.Str2036Key)]
    public ChartLineElement Up { get; }

    /// <summary>
    /// <see cref="Fractals.Down"/> dots color.
    /// </summary>
    [Display(
        ResourceType = typeof(LocalizedStrings),
        Name = LocalizedStrings.Str2037Key,
        Description = LocalizedStrings.Str2038Key)]
    public ChartLineElement Down { get; }
...
}

In the FractalsPainter designer, we set them the values and basic properties - the color, thickness, and drawing style. Then add them as the chart child element:

C#
...
    /// <summary>
    /// Create instance.
    /// </summary>
    public FractalsPainter()
    {
        Up = new ChartLineElement { Color = Colors.Green };
        Down = new ChartLineElement { Color = Colors.Red };

        Up.Style = Down.Style = ChartIndicatorDrawStyles.Dot;
        Up.StrokeThickness = Down.StrokeThickness = 4;

        AddChildElement(Up);
        AddChildElement(Down);
    }
...

Override the OnDraw method in which we draw the indicator using the DrawValues(IIndicator, IChartElement) method:

C#
...
    /// <inheritdoc />
    protected override bool OnDraw()
    {
        var ind = (Fractals)Indicator;
        var result = false;

        result |= DrawValues(ind.Down, Down);
        result |= DrawValues(ind.Up, Up);

        return result;
    }
...

Full FractalsPainter code:

C#
/// <summary>
/// The chart element for <see cref="Fractals"/>.
/// </summary>
[Indicator(typeof(Fractals))]
public class FractalsPainter : BaseChartIndicatorPainter
{
    /// <summary>
    /// <see cref="Fractals.Up"/> dots color.
    /// </summary>
    [Display(
        ResourceType = typeof(LocalizedStrings),
        Name = LocalizedStrings.Str2035Key,
        Description = LocalizedStrings.Str2036Key)]
    public ChartLineElement Up { get; }

    /// <summary>
    /// <see cref="Fractals.Down"/> dots color.
    /// </summary>
    [Display(
        ResourceType = typeof(LocalizedStrings),
        Name = LocalizedStrings.Str2037Key,
        Description = LocalizedStrings.Str2038Key)]
    public ChartLineElement Down { get; }

    /// <summary>
    /// Create instance.
    /// </summary>
    public FractalsPainter()
    {
        Up = new ChartLineElement { Color = Colors.Green };
        Down = new ChartLineElement { Color = Colors.Red };

        Up.Style = Down.Style = ChartIndicatorDrawStyles.Dot;
        Up.StrokeThickness = Down.StrokeThickness = 4;

        AddChildElement(Up);
        AddChildElement(Down);
    }

    /// <inheritdoc />
    protected override bool OnDraw()
    {
        var ind = (Fractals)Indicator;
        var result = false;

        result |= DrawValues(ind.Down, Down);
        result |= DrawValues(ind.Up, Up);

        return result;
    }

    #region IPersistable

    /// <inheritdoc />
    public override void Load(SettingsStorage storage)
    {
        base.Load(storage);

        Up.Load(storage.GetValue<SettingsStorage>(nameof(Up)));
        Down.Load(storage.GetValue<SettingsStorage>(nameof(Down)));
    }

    /// <inheritdoc />
    public override void Save(SettingsStorage storage)
    {
        base.Save(storage);

        storage.SetValue(nameof(Up), Up.Save());
        storage.SetValue(nameof(Down), Down.Save());
    }

    #endregion
}