public MainViewModel(IDiagnosticsViewModel diagnosticsViewModel,
                             ITabularDataService tabularDataService,
                             IColumnsService columnsService,
                             IOverlayService overlayService,
                             IDateTimeService dateTimeService,
                             ISchedulerService schedulerService)
        {
            _tabularDataService = tabularDataService;
            _schedulerService   = schedulerService;
            _columnsService     = columnsService;
            _overlayService     = overlayService;
            _dateTimeService    = dateTimeService;
            Diagnostics         = diagnosticsViewModel;

            _dataIds        = new Dictionary <object, DynamicDataViewModel>(1000);
            _data           = new CustomTypeRangeObservableCollection <DynamicDataViewModel>();
            _collectionView = new ListCollectionView(_data)
            {
                Filter = FilterData
            };

            _updateStats = new Dictionary <long, int>();

            RefreshCommand = ReactiveCommand.Create()
                             .DisposeWith(this);

            ClearCommand = ReactiveCommand.Create()
                           .DisposeWith(this);

            ColumnPickerCommand = ReactiveCommand.Create(HasDataChanged)
                                  .DisposeWith(this);

            _dataStream = InitialiseAndProcessDataAsync()
                          .DisposeWith(this);

            RefreshCommand.Subscribe(x => Refresh())
            .DisposeWith(this);

            ClearCommand.Subscribe(x => Clear())
            .DisposeWith(this);

            ColumnPickerCommand.Subscribe(x => ShowColumnPicker())
            .DisposeWith(this);

            _suspendNotifications = new SerialDisposable()
                                    .DisposeWith(this);

            FilterChanged.Subscribe(x => _collectionView.Refresh())
            .DisposeWith(this);

            ColumnsChanged.ObserveOn(schedulerService.Dispatcher)
            .Subscribe(x => OnPropertyChanged(nameof(VisibleColumns)))
            .DisposeWith(this);

            Disposable.Create(() => Clear())
            .DisposeWith(this);
        }
        public MainViewModel(IDiagnosticsViewModel diagnosticsViewModel,
                             ITabularDataService tabularDataService,
                             IColumnsService columnsService,
                             IOverlayService overlayService,
                             IDateTimeService dateTimeService,
                             ISchedulerService schedulerService)
        {
            _tabularDataService = tabularDataService;
            _schedulerService   = schedulerService;
            _columnsService     = columnsService;
            _dateTimeService    = dateTimeService;
            Diagnostics         = diagnosticsViewModel;

            _dataIds        = new Dictionary <object, DynamicDataViewModel>(1000);
            _data           = new CustomTypeRangeObservableCollection <DynamicDataViewModel>();
            _collectionView = new ListCollectionView(_data)
            {
                Filter = FilterData
            };

            _updateStats = new Dictionary <long, int>();

            _updates = new Subject <int>()
                       .DisposeWith(this);

            var refreshEnabled = new BehaviorSubject <bool>(true)
                                 .DisposeWith(this);

            _filterRefresh = new Subject <Unit>()
                             .DisposeWith(this);

            _dataDisposable = new SerialDisposable()
                              .DisposeWith(this);

            RefreshCommand = ReactiveCommand.Create(refreshEnabled.DistinctUntilChanged())
                             .DisposeWith(this);

            ClearCommand = ReactiveCommand.Create(refreshEnabled.DistinctUntilChanged())
                           .DisposeWith(this);

            ColumnPickerCommand = ReactiveCommand.Create(_data.ObserveCollectionChanged().Select(x => _data.Any()))
                                  .DisposeWith(this);

            RefreshCommand.ActivateGestures()
            .StartWith(Constants.StartsWith.Unit.DefaultBoxed)
            .ResilentSubscribe(_ =>
            {
                refreshEnabled.OnNext(false);
                DisposeOfData();

                _dataDisposable.Disposable = _tabularDataService.GetAsync(schedulerService.TaskPool)
                                             .Select(x => ConvertToDataSet(x))
                                             .ObserveOn(schedulerService.Dispatcher)
                                             .ResilentSubscribe(x =>
                {
                    ProcessDataSet(x);
                    refreshEnabled.OnNext(true);
                }, schedulerService.Dispatcher);
            }, schedulerService.Dispatcher)
            .DisposeWith(this);

            ClearCommand.ActivateGestures()
            .ResilentSubscribe(x => DisposeOfData(), schedulerService.Dispatcher)
            .DisposeWith(this);

            ColumnPickerCommand.ActivateGestures()
            .ResilentSubscribe(x =>
            {
                var viewModel = new ColumnPickerViewModel(GridName, _columnsService, schedulerService);
                overlayService.Post("Column Picker", viewModel, viewModel);
            }, schedulerService.Dispatcher)
            .DisposeWith(this);

            Disposable.Create(() => DisposeOfData())
            .DisposeWith(this);

            _suspendNotifications = new SerialDisposable()
                                    .DisposeWith(this);

            _filterRefresh.Throttle(Constants.UI.Grids.FilterThrottle, schedulerService.TaskPool)
            .ObserveOn(schedulerService.Dispatcher)
            .ActivateGestures()
            .Subscribe(x =>
            {
                using (Duration.Measure(Logger, "Refresh"))
                    _collectionView.Refresh();
            })
            .DisposeWith(this);

            columnsService.Changed
            .Where(x => x == GridName)
            .ObserveOn(schedulerService.Dispatcher)
            .ResilentSubscribe(x => OnPropertyChanged(() => VisibleColumns), schedulerService.Dispatcher)
            .DisposeWith(this);

            _updates.Buffer(Constants.UI.Grids.UpdatesInfoThrottle, schedulerService.TaskPool)
            .Where(x => x.Any())
            .Select(x => x.Last())
            .ObserveOn(schedulerService.Dispatcher)
            .Subscribe(x => UpdatesPerSecond = x)
            .DisposeWith(this);
        }