Горизонтальная линия

Тема в разделе "Примеры графических объектов", создана пользователем Support, 6 янв 2020.

  1. Support

    Support Администратор
    Команда форума

    Регистрация:
    5 сен 2015
    Сообщения:
    1 149
    Симпатии:
    250
    Код графического объекта Горизонтальная линия
    1. //------------------------------------------------------------------------------
    2. //
    3. // Графический объект HorizontalLine. Copyright (c) 2020 Ilya Smirnov. All rights reserved.
    4. //
    5. //------------------------------------------------------------------------------
    6.  
    7. using System;
    8. using System.Collections.Generic;
    9. using System.ComponentModel;
    10. using System.Runtime.Serialization;
    11. using System.Windows;
    12. using System.Windows.Media;
    13. using TigerTrade.Chart.Alerts;
    14. using TigerTrade.Chart.Base;
    15. using TigerTrade.Chart.Base.Enums;
    16. using TigerTrade.Chart.Indicators.Common;
    17. using TigerTrade.Chart.Objects.Common;
    18. using TigerTrade.Chart.Objects.Enums;
    19. using TigerTrade.Core.Utils.Logging;
    20. using TigerTrade.Dx;
    21. using TigerTrade.Dx.Enums;
    22.  
    23. namespace TigerTrade.Chart.Objects.Custom
    24. {
    25.     [DataContract(Name = "HorizontalLineObject", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Objects.Custom")]
    26.     [ChartObject("X_HorizontalLine", "Горизонтальная линия", 1, Type = typeof(HorizontalLineObject))]
    27.     public class HorizontalLineObject : ObjectBase
    28.     {
    29.         [Category("Цена"), DisplayName("Цена")]
    30.         public decimal Price
    31.         {
    32.             get => (decimal)ControlPoints[0].Y;
    33.             set
    34.             {
    35.                 if (value == (decimal)ControlPoints[0].Y)
    36.                 {
    37.                     return;
    38.                 }
    39.  
    40.                 ControlPoints[0].Y = (double)value;
    41.  
    42.                 OnPropertyChanged();
    43.                 OnPropertyChanged(nameof(ControlPoints));
    44.             }
    45.         }
    46.  
    47.         private ChartAlertSettings _alert;
    48.  
    49.         [DataMember(Name = "Alert")]
    50.         [Category("Оповещение"), DisplayName("Оповещение")]
    51.         public ChartAlertSettings Alert
    52.         {
    53.             get => _alert ?? (_alert = new ChartAlertSettings());
    54.             set
    55.             {
    56.                 if (Equals(value, _alert))
    57.                 {
    58.                     return;
    59.                 }
    60.  
    61.                 _alert = value;
    62.  
    63.                 OnPropertyChanged();
    64.             }
    65.         }
    66.  
    67.         private int _alertMinDistance;
    68.  
    69.         [DataMember(Name = "AlertMinDistance")]
    70.         [Category("Оповещение"), DisplayName("Мин. расстояние")]
    71.         public int AlertMinDistance
    72.         {
    73.             get => _alertMinDistance;
    74.             set
    75.             {
    76.                 if (value == _alertMinDistance)
    77.                 {
    78.                     return;
    79.                 }
    80.  
    81.                 _alertMinDistance = value;
    82.  
    83.                 OnPropertyChanged();
    84.             }
    85.         }
    86.  
    87.         private string _text;
    88.  
    89.         [DataMember(Name = "Text")]
    90.         [Category("Текст"), DisplayName("Текст")]
    91.         public string Text
    92.         {
    93.             get => _text;
    94.             set
    95.             {
    96.                 if (value == _text)
    97.                 {
    98.                     return;
    99.                 }
    100.  
    101.                 _text = value;
    102.  
    103.                 OnPropertyChanged();
    104.             }
    105.         }
    106.  
    107.         private ObjectTextAlignment _textAlignment;
    108.  
    109.         [DataMember(Name = "TextAlignment")]
    110.         [Category("Текст"), DisplayName("Расположение")]
    111.         public ObjectTextAlignment TextAlignment
    112.         {
    113.             get => _textAlignment;
    114.             set
    115.             {
    116.                 if (value == _textAlignment)
    117.                 {
    118.                     return;
    119.                 }
    120.  
    121.                 _textAlignment = value;
    122.  
    123.                 OnPropertyChanged();
    124.             }
    125.         }
    126.  
    127.         private int _fontSize;
    128.  
    129.         [DataMember(Name = "FontSize")]
    130.         [Category("Текст"), DisplayName("Размер")]
    131.         public int FontSize
    132.         {
    133.             get => _fontSize;
    134.             set
    135.             {
    136.                 value = Math.Max(10, Math.Min(100, value));
    137.  
    138.                 if (value == _fontSize)
    139.                 {
    140.                     return;
    141.                 }
    142.  
    143.                 _fontSize = value;
    144.  
    145.                 OnPropertyChanged();
    146.             }
    147.         }
    148.  
    149.         private XBrush _lineBrush;
    150.  
    151.         private XPen _linePen;
    152.  
    153.         private XColor _lineColor;
    154.  
    155.         [DataMember(Name = "LineColor")]
    156.         [Category("Линия"), DisplayName("Цвет линии")]
    157.         public XColor LineColor
    158.         {
    159.             get => _lineColor;
    160.             set
    161.             {
    162.                 if (value == _lineColor)
    163.                 {
    164.                     return;
    165.                 }
    166.  
    167.                 _lineColor = value;
    168.  
    169.                 _lineBrush = new XBrush(_lineColor);
    170.                 _linePen = new XPen(_lineBrush, LineWidth, LineStyle);
    171.  
    172.                 OnPropertyChanged();
    173.             }
    174.         }
    175.  
    176.         private int _lineWidth;
    177.  
    178.         [DataMember(Name = "LineWidth")]
    179.         [Category("Линия"), DisplayName("Толщина линии")]
    180.         public int LineWidth
    181.         {
    182.             get => _lineWidth;
    183.             set
    184.             {
    185.                 value = Math.Max(1, Math.Min(10, value));
    186.  
    187.                 if (value == _lineWidth)
    188.                 {
    189.                     return;
    190.                 }
    191.  
    192.                 _lineWidth = value;
    193.  
    194.                 _linePen = new XPen(_lineBrush, _lineWidth, LineStyle);
    195.  
    196.                 OnPropertyChanged();
    197.             }
    198.         }
    199.  
    200.         private XDashStyle _lineStyle;
    201.  
    202.         [DataMember(Name = "LineStyle")]
    203.         [Category("Линия"), DisplayName("Стиль линии")]
    204.         public XDashStyle LineStyle
    205.         {
    206.             get => _lineStyle;
    207.             set
    208.             {
    209.                 if (value == _lineStyle)
    210.                 {
    211.                     return;
    212.                 }
    213.  
    214.                 _lineStyle = value;
    215.  
    216.                 _linePen = new XPen(_lineBrush, LineWidth, _lineStyle);
    217.  
    218.                 OnPropertyChanged();
    219.             }
    220.         }
    221.  
    222.         protected override int PenWidth => LineWidth;
    223.  
    224.         private Rect _lineRect;
    225.  
    226.         public HorizontalLineObject()
    227.         {
    228.             AlertMinDistance = 3;
    229.  
    230.             Text = "";
    231.             TextAlignment = ObjectTextAlignment.RightTop;
    232.  
    233.             FontSize = 14;
    234.  
    235.             LineColor = Colors.Black;
    236.             LineWidth = 1;
    237.             LineStyle = XDashStyle.Solid;
    238.         }
    239.  
    240.         protected override void Draw(DxVisualQueue visual, ref List<ObjectLabelInfo> labels)
    241.         {
    242.             if (Canvas == null)
    243.             {
    244.                 return;
    245.             }
    246.  
    247.             var point = ToPoint(ControlPoints[0]);
    248.  
    249.             var startPoint = new Point(Canvas.Rect.Left, point.Y);
    250.             var endPoint = new Point(Canvas.Rect.Right, point.Y);
    251.  
    252.             _lineRect = new Rect(startPoint, endPoint);
    253.  
    254.             if (Settings.TransformHorLines && Canvas.IsStock &&
    255.                 Canvas.StockType == ChartStockType.Clusters)
    256.             {
    257.                 var y = ControlPoints[0].Y;
    258.  
    259.                 var step = DataProvider.Step;
    260.  
    261.                 var price = (long)Math.Round(y / step);
    262.  
    263.                 var y1 = GetY((price + .5) * step);
    264.                 var y2 = GetY((price - .5) * step);
    265.  
    266.                 if (y2 - y1 > LineWidth + 2)
    267.                 {
    268.                     var brush = new XBrush(LineColor, LineColor.Alpha > 127 ? 127 : LineColor.Alpha);
    269.  
    270.                     _lineRect = new Rect(new Point(startPoint.X, y1), new Point(endPoint.X, y2));
    271.  
    272.                     visual.FillRectangle(brush, _lineRect);
    273.  
    274.                     DrawText(visual);
    275.  
    276.                     labels.Add(new ObjectLabelInfo(price * step, y1, y2, LineColor));
    277.  
    278.                     return;
    279.                 }
    280.             }
    281.  
    282.             visual.DrawLine(_linePen, startPoint, endPoint);
    283.  
    284.             DrawText(visual);
    285.  
    286.             labels.Add(new ObjectLabelInfo(ControlPoints[0].Y, LineColor));
    287.         }
    288.  
    289.         protected void DrawText(DxVisualQueue visual)
    290.         {
    291.             if (string.IsNullOrEmpty(Text) || TextAlignment == ObjectTextAlignment.Hide)
    292.             {
    293.                 return;
    294.             }
    295.  
    296.             var font = new XFont(Canvas.ChartFont.Name, FontSize);
    297.  
    298.             var textSize = font.GetSize(Text);
    299.  
    300.             var x = 0.0;
    301.             var y = 0.0;
    302.  
    303.             var width = textSize.Width;
    304.  
    305.             switch (TextAlignment)
    306.             {
    307.                 case ObjectTextAlignment.LeftTop:
    308.                 case ObjectTextAlignment.CenterTop:
    309.                 case ObjectTextAlignment.RightTop:
    310.  
    311.                     y = _lineRect.Top - 4 - textSize.Height;
    312.  
    313.                     break;
    314.  
    315.                 case ObjectTextAlignment.LeftMiddle:
    316.                 case ObjectTextAlignment.CenterMiddle:
    317.                 case ObjectTextAlignment.RightMiddle:
    318.  
    319.                     y = (_lineRect.Top + _lineRect.Bottom - textSize.Height) / 2.0;
    320.  
    321.                     break;
    322.  
    323.                 case ObjectTextAlignment.LeftBottom:
    324.                 case ObjectTextAlignment.CenterBottom:
    325.                 case ObjectTextAlignment.RightBottom:
    326.  
    327.                     y = _lineRect.Bottom + 4;
    328.  
    329.                     break;
    330.             }
    331.  
    332.             switch (TextAlignment)
    333.             {
    334.                 case ObjectTextAlignment.LeftTop:
    335.                 case ObjectTextAlignment.LeftMiddle:
    336.                 case ObjectTextAlignment.LeftBottom:
    337.  
    338.                     x = _lineRect.X;
    339.  
    340.                     break;
    341.  
    342.                 case ObjectTextAlignment.CenterTop:
    343.                 case ObjectTextAlignment.CenterMiddle:
    344.                 case ObjectTextAlignment.CenterBottom:
    345.  
    346.                     x = _lineRect.Right - (_lineRect.Width + width) / 2.0;
    347.  
    348.                     x = Math.Max(x, _lineRect.Left);
    349.  
    350.                     break;
    351.  
    352.                 case ObjectTextAlignment.RightTop:
    353.                 case ObjectTextAlignment.RightMiddle:
    354.                 case ObjectTextAlignment.RightBottom:
    355.  
    356.                     x = _lineRect.Right - width;
    357.  
    358.                     x = Math.Max(x, _lineRect.Left);
    359.  
    360.                     break;
    361.             }
    362.  
    363.             var rect = new Rect(x, y, width, textSize.Height);
    364.  
    365.             visual.DrawString(Text, font, _lineBrush, rect);
    366.         }
    367.  
    368.         public override void DrawControlPoints(DxVisualQueue visual)
    369.         {
    370.             if (_lineRect == Rect.Empty)
    371.             {
    372.                 return;
    373.             }
    374.  
    375.             var width = LineWidth / 2 + 4;
    376.  
    377.             var center = new Point((_lineRect.Left + _lineRect.Right) / 2.0, (_lineRect.Top + _lineRect.Bottom) / 2.0);
    378.  
    379.             var rect = new Rect(center, center);
    380.  
    381.             rect.Inflate(new Size(width, width));
    382.  
    383.             visual.FillRectangle(Theme.ChartCpFillBrush, rect);
    384.             visual.DrawRectangle(Theme.ChartCpLinePen, rect);
    385.         }
    386.  
    387.         protected override bool InObject(int x, int y)
    388.         {
    389.             if (_lineRect == Rect.Empty)
    390.             {
    391.                 return false;
    392.             }
    393.  
    394.             var r = Rect.Inflate(_lineRect, new Size(0, 2));
    395.  
    396.             return r.Contains(x, y);
    397.         }
    398.  
    399.         protected override bool IsObjectOnChart()
    400.         {
    401.             return true;
    402.         }
    403.  
    404.         public override void ApplyTheme(IChartTheme theme)
    405.         {
    406.             base.ApplyTheme(theme);
    407.  
    408.             LineColor = theme.ChartObjectLineColor;
    409.         }
    410.  
    411.         public override void CopyTemplate(ObjectBase objectBase, bool style)
    412.         {
    413.             if (objectBase is HorizontalLineObject obj)
    414.             {
    415.                 Alert.Copy(obj.Alert, !style);
    416.  
    417.                 OnPropertyChanged(nameof(Alert));
    418.  
    419.                 AlertMinDistance = obj.AlertMinDistance;
    420.  
    421.                 Text = obj.Text;
    422.                 TextAlignment = obj.TextAlignment;
    423.  
    424.                 FontSize = obj.FontSize;
    425.  
    426.                 LineColor = obj.LineColor;
    427.                 LineWidth = obj.LineWidth;
    428.                 LineStyle = obj.LineStyle;
    429.             }
    430.  
    431.             base.CopyTemplate(objectBase, style);
    432.         }
    433.  
    434.         private double _lastAlertValue;
    435.         private int _lastAlertIndex;
    436.  
    437.         public override void CheckAlert(List<IndicatorBase> indicators)
    438.         {
    439.             if (!Alert.IsActive)
    440.             {
    441.                 return;
    442.             }
    443.  
    444.             try
    445.             {
    446.                 foreach (var indicator in indicators)
    447.                 {
    448.                     if (indicator.CheckAlert(ControlPoints[0].Y, AlertMinDistance, ref _lastAlertIndex,
    449.                         ref _lastAlertValue))
    450.                     {
    451.                         var message =
    452.                             $"{indicator.Name}: пересечение уровня {DataProvider.Symbol.FormatPrice((decimal) ControlPoints[0].Y)}.";
    453.  
    454.                         AddAlert(Alert, message);
    455.                     }
    456.                 }
    457.             }
    458.             catch (Exception e)
    459.             {
    460.                 LogManager.WriteError(e);
    461.             }
    462.         }
    463.     }
    464. }