namespace Ecng.Trading.Xaml { using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Windows; using AmCharts.Windows.Stock; using AmCharts.Windows.Stock.Data; using Ecng.Common; using Ecng.Trading.BusinessEntities; using Ecng.Collections; /// /// Графический компонент отображения графиков. /// [CLSCompliant(false)] public partial class ChartControl { private sealed class CustomChartIndicatorList : BaseCollection where T : class { private readonly ObservableCollection _inner; private readonly Dictionary _dict = new Dictionary(); public CustomChartIndicatorList( ObservableCollection inner) { if (inner == null) throw new ArgumentNullException("inner"); _inner = inner; } protected override void OnAdding(T item) { var time = GetTime(item); var old = _dict.TryGetValue(time); if (old != null) _inner.Remove(item); _inner.Add(item); _dict[time] = item; base.OnAdding(item); } protected override void OnRemoving(T item) { _inner.Remove(item); _dict.Remove(GetTime(item)); base.OnRemoving(item); } protected override void OnInserting(int index, T item) { OnAdding(item); base.OnInserting(index, item); } protected override void OnClearing() { _inner.Clear(); _dict.Clear(); base.OnClearing(); } private static DateTime GetTime(T item) { if (item == null) throw new ArgumentNullException("item"); if (item is Candle) return item.To().Time; else if (item is Order) return item.To().Time; else return item.To().Time; } } /// /// Создать . /// public ChartControl() { this.DataContext = this; var candlesSource = new ObservableCollection(); var ordersSource = new ObservableCollection(); this.Candles = new CustomChartIndicatorList(candlesSource); this.Orders = new CustomChartIndicatorList(ordersSource); InitializeComponent(); _stockChart.DataSets[0].ItemsSource = candlesSource; _stockChart.DataSets[1].ItemsSource = ordersSource; _stockChart.EndDate = DateTime.Now; _stockChart.StartDate = _stockChart.EndDate - TimeSpan.FromTicks(TimeSpanEx.TicksPerYear); } /// /// Коллекция свечек, по которым строить график OHLC. /// public ICollection Candles { get; private set; } /// /// Коллекция заявок, по которым рисуются сигналы на покупку и продажу. /// public ICollection Orders { get; private set; } /// /// Создать дополнительный тренд. /// /// Заголовок нового тренда. /// Тип нового тренда. /// Коллекция с данными, которую необходимо заполнять для перерисовки созданного тренда. [CLSCompliant(false)] public ICollection CreateTrend(string title, GraphType type) { var source = new ObservableCollection(); var dataSet = new DataSet { Title = title, ShortTitle = title, ItemsSource = source, DateMemberPath = "Time", ValueMemberPath = "Value", ID = title, }; _stockChart.DataSets.Add(dataSet); _mainChart.Graphs.Add(new Graph { DataSet = dataSet, GraphType = type, Style = (Style)_stockChart.Resources["sharedGraphSettings"], }); return new CustomChartIndicatorList(source); } } }