private LineSeries CreateLineSeriesAndAxis(SymbolObservationViewModel symbol)
        {
            var lineSeries = new LineSeries();

            lineSeries.Title = symbol.Name;

            var index = PlotModel.Axes.Count - 1;

            var axis = new LinearAxis
            {
                AxislineThickness = 2,
                AxislineColor     = PlotModel.DefaultColors[index],
                MinorTickSize     = 4,
                MajorTickSize     = 7,
                TicklineColor     = PlotModel.DefaultColors[index],
                TextColor         = PlotModel.DefaultColors[index],
                AxisDistance      = PlotModel.Axes.OfType <LinearAxis>().Count() * 50,
                Position          = AxisPosition.Left,
                IsZoomEnabled     = false,
                Key            = symbol.Name,
                Tag            = symbol.Name,
                MinimumPadding = 0.1,
                MaximumPadding = 0.1
            };

            lineSeries.YAxisKey = symbol.Name;

            PlotModel.Axes.Add(axis);
            PlotModel.Series.Add(lineSeries);
            return(lineSeries);
        }
        private IDisposable CreateSymbolLineSeries(SymbolObservationViewModel symbol)
        {
            var lineSeries = CreateLineSeriesAndAxis(symbol);
            var disposable = new CompositeDisposable();

            RescaleAxisDistances();

            dataPoints[symbol.Name] = new List <DataPoint> {
                DateTimeAxis.CreateDataPoint(DateTime.Now, Convert.ToDouble(symbol.Value))
            };


            Observable.FromEventPattern <PropertyChangedEventHandler, PropertyChangedEventArgs>(
                handler => handler.Invoke,
                h => symbol.PropertyChanged += h,
                h => symbol.PropertyChanged -= h)
            .Where(args => args.EventArgs.PropertyName == "Value" && pause == false)
            .ObserveOnDispatcher()
            .Subscribe(x => { UpdateDatapoints(symbol); }).AddDisposableTo(disposable);


            Observable.Interval(TimeSpan.FromSeconds(1))
            .Where(x => pause == false)
            .ObserveOnDispatcher()
            .Subscribe(x => { UpdateLineseries(symbol, lineSeries); })
            .AddDisposableTo(disposable);

            raisePropertyChanged("PlotModel");

            // Need to invalidate oxyplot graph after removal of line series in order to have it really removed from UI
            Disposable.Create(() => PlotModel.InvalidatePlot(true))
            .AddDisposableTo(disposable);

            return(disposable);
        }
        public void AddSymbol(SymbolObservationViewModel symbol)
        {
            var symbolInLineSeries = PlotModel.Series.FirstOrDefault(series => series.Title == symbol.Name);

            if (symbolInLineSeries == null)
            {
                symbolCache.AddOrUpdate(symbol);
            }
        }
        private void UpdateDatapoints(SymbolObservationViewModel symbol)
        {
            var refreshTime = DateTime.Now;

            dataPoints[symbol.Name].Add(DateTimeAxis.CreateDataPoint(refreshTime, Convert.ToDouble(symbol.Value)));

            var expireLimit = DateTimeAxis.ToDouble(DateTime.Now.Subtract(ExpiresAfter));

            dataPoints[symbol.Name].RemoveAll(point => point.X < expireLimit);
        }
        private void UpdateLineseries(SymbolObservationViewModel symbol, LineSeries lineSeries)
        {
            var newPoints = dataPoints[symbol.Name]
                            .Where(point => !lineSeries.Points.Select(oldPoint => oldPoint.X).Contains(point.X));

            if (!newPoints.Any() && dataPoints[symbol.Name].Any())
            {
                var lastPoint = dataPoints[symbol.Name].LastOrDefault();
                newPoints = new[] { DateTimeAxis.CreateDataPoint(DateTime.Now, lastPoint.Y) };
            }

            lineSeries.Points.AddRange(newPoints);

            var expireLimit = DateTimeAxis.ToDouble(DateTime.Now.Subtract(ExpiresAfter));

            lineSeries.Points.RemoveAll(point => point.X < expireLimit);

            PlotModel.InvalidatePlot(true);
            raisePropertyChanged("PlotModel");
        }
        public void RemoveSymbol(SymbolObservationViewModel symbol)
        {
            symbolCache.Remove(symbol.Name);

            var seriesToRemove = PlotModel.Series.FirstOrDefault(series => series.Title == symbol.Name);

            if (seriesToRemove != null)
            {
                PlotModel.Series.Remove(seriesToRemove);
            }

            var axisToRemove = PlotModel.Axes.FirstOrDefault(axis => axis.Key == symbol.Name);

            if (axisToRemove != null)
            {
                PlotModel.Axes.Remove(axisToRemove);
            }

            RescaleAxisDistances();
        }