指标图形渲染器
有些指标需要特殊的绘图样式,例如 BollingerBands 指标需要两条线,或者 Fractals 指标需要点。在这些情况下,您需要在 ChartIndicatorElement 中明确指定指标的图形渲染器。
var chartIndicatorElement = new ChartIndicatorElement()
{
IndicatorPainter = new BollingerBandsPainter(),
};
让我们以 Fractals 指标为例,考虑如何创建自定义 IndicatorPainter。
所有 IndicatorPainters 必须继承自基类 BaseChartIndicatorPainter<TIndicator>,或实现接口 IChartIndicatorPainter:
/// <summary>
/// 用于 <see cref="Fractals"/> 的图表元素。
/// </summary>
[Indicator(typeof(Fractals))]
public class FractalsPainter : BaseChartIndicatorPainter<Fractals>
{
...
}
让我们定义将表示上部和下部分形的图表元素 ChartLineElement:
/// <summary>
/// 用于 <see cref="Fractals"/> 的图表元素。
/// </summary>
[Indicator(typeof(Fractals))]
public class FractalsPainter : BaseChartIndicatorPainter<Fractals>
{
/// <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; }
...
}
在 FractalsPainter 的构造函数中,我们设置它们的值和主要属性,例如颜色、粗细和绘图样式。之后,我们将它们作为图表的子元素添加进去:
...
/// <summary>
/// 创建实例。
/// </summary>
public FractalsPainter()
{
Up = new ChartLineElement { Color = Colors.Green };
Down = new ChartLineElement { Color = Colors.Red };
Up.Style = Down.Style = DrawStyles.Dot;
Up.StrokeThickness = Down.StrokeThickness = 4;
AddChildElement(Up);
AddChildElement(Down);
}
...
重写 OnDraw 方法,在该方法中,我们使用 DrawValues 方法绘制指示器:
...
/// <inheritdoc />
protected override bool OnDraw(Fractals ind, IDictionary<IIndicator, IList<ChartDrawData.IndicatorData>> data)
{
var result = false;
result |= DrawValues(data[ind.Down], Down);
result |= DrawValues(data[ind.Up], Up);
return result;
}
...
FractalsPainter 的完整代码:
/// <summary>
/// 用于 <see cref="Fractals"/> 的图表元素。
/// </summary>
[Indicator(typeof(Fractals))]
public class FractalsPainter : BaseChartIndicatorPainter<Fractals>
{
/// <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>
/// 创建实例。
/// </summary>
public FractalsPainter()
{
Up = new ChartLineElement { Color = Colors.Green };
Down = new ChartLineElement { Color = Colors.Red };
Up.Style = Down.Style = DrawStyles.Dot;
Up.StrokeThickness = Down.StrokeThickness = 4;
AddChildElement(Up);
AddChildElement(Down);
}
/// <inheritdoc />
protected override bool OnDraw(Fractals ind, IDictionary<IIndicator, IList<ChartDrawData.IndicatorData>> data)
{
var result = false;
result |= DrawValues(data[ind.Down], Down);
result |= DrawValues(data[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
}