Multiple Dynamic Series in MVVM

3 posts, 0 answers
  1. Martyn
    Martyn avatar
    18 posts
    Member since:
    Mar 2011

    Posted 29 Feb 2012 Link to this post

    Hello,

    I currently have a set of RadChart's where some of them contain multiple series grouped into categories.

    I am investigating whether this is possible with RadChartView using a MVVM pattern, as I do not know how many series I will have in advance and all the examples I can find of dynamic series, involve adding the series to the chart in code behind, which is not possible in MVVM as I do not have access to the RadChart instance in the View Model.

    Is what I am trying to accomplish possible with RadChartView?

    Thanks very much,

    Martyn.
  2. Giuseppe
    Admin
    Giuseppe avatar
    2363 posts

    Posted 05 Mar 2012 Link to this post

    Hello Martyn,

    Currently RadChartView does not provide support for adding unknown number of series dynamically at runtime in MVVM. We have discussed this scenario internally and in order to support it we will most probably introduce new composite control (it will probably inherit from RadCartesianChart) that will take care of the "plumbing" part (i.e. the code logic for dynamically adding / removing series based on some grouping rules) and will provide MVVM-friendly user interface. Note, however, that this composite control will not be available for the Q2 2012 release (around June) and we still haven't confirmed our product backlog for the Q3 2012 release.

    Sorry for the inconvenience.


    Kind regards,
    Giuseppe
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  3. DevCraft banner
  4. YongKoo Kang
    YongKoo Kang avatar
    101 posts
    Member since:
    Jan 2010

    Posted 06 Mar 2012 Link to this post

    Hi Martyn,

    I had similar usecase, and sovled by involving manager viewmodel which has a reference
    of chartView/chartViewModel. I'm not sure it would be helpful in your usecase,
    but pls be refered. My usecase was to display line chart in real time with temperatures
    of several parts of machine,which has unknown numer of sensor(2 ~ 5 EA per machine).

    ViewModel can create multiple dynamic series if he has a refernce of RadChart,
    so I have no chice to set this when creating chart viewmodel as such.

    // thermo view is chart view
    // and _thermovm is his view model.
     
       public FrameworkElement ThermoView
            {
                get
                {
                    if (_thermoView == null)
                    {
                        var thermView = new DynamicThermoView();
                          
                        // set RadChart reference
                        _thermoVm = new DynamicThermoViewModel(this, thermView.RadChart1);
     
                        thermView.DataContext = _thermoVm;
                        _thermoView = thermView;
                    }
                    DetachFromVisualParent(_thermoView);
     
                    return _thermoView;
                }
            }

    And then multiple series are created as follows;

    // this was called whenever new temperature has beed arrived
    // in his parent-parent manager object.
    // ThermoHead : series business object of each part.
    // When heat type is not yet created in series list,create it and bind.
     
     
       private void UpdateHeat(int heatType, int heatTime, int heat)
            {
                ThermoHead series = _seriesList.SingleOrDefault(k => k.HeatType.Equals(heatType));
                if (series == null)
                {
                    // create series and add into colelction
                    series = new ThermoHead(heatType, PopTagTypeEnumsMapper.DisplayStringfromEnum((PopTagTypeEnums)heatType));
                    _seriesList.Add(series);
                    // add new series in chart
                    AddSeries();
                }
                // push heat data
                series.HeatCollection.SuspendNotifications();
                if (series.HeatCollection.Count > _maxCount)
                    series.HeatCollection.RemoveAt(0);
                series.HeatCollection.Add(new SeriesData(DateTime.Now, heat));
                series.HeatCollection.ResumeNotifications();
            }
     
            #region chart method
     
            // _chart is reference of radChart .
     
            internal void AddSeries()
            {
                foreach (var head in _seriesList)
                {
                    // chk exists in chart
                    var exist = _chart.Series.SingleOrDefault(k => k.Name.Equals(head.HeatName));
                    if (exist != null)
                        continue;
     
                    LineSeries series = new LineSeries();
                    series.CategoryBinding = new PropertyNameDataPointBinding("TimeStamp");
                    series.ValueBinding = new PropertyNameDataPointBinding("Value");
                    series.Name = head.HeatName;
                    series.ItemsSource = head.HeatCollection;
                    _chart.Series.Add(series);
                }
                // my other method releted
                CreateLegendColor(_chart.Series[0]);
                RefreshChart();
            }
     
     
      public class ThermoHead
        {
            public int HeatType {get;set;}
            public string HeatName {get;set;}
            public RadObservableCollection<SeriesData> HeatCollection  {get;set;}
     
            public ThermoHead(int heatType, string typeName)
            {
                HeatType = heatType;
                HeatName = typeName;
                HeatCollection = new RadObservableCollection<SeriesData>();
            }
        }
     
     public class SeriesData
        {
            private DateTime _timeStamp;
            private decimal _value;
            private string _category;
     
            public SeriesData(DateTime timeStamp, decimal value)
            {
                this._timeStamp = timeStamp;
                this._value = value;
            }
     
            public SeriesData(string category, decimal value)
            {
                this._category = category;
                this._value = value;
            }
     
            public DateTime TimeStamp
            {
                get
                {
                    return this._timeStamp;
                }
                set
                {
                    if (this._timeStamp != value)
                    {
                        this._timeStamp = value;
                    }
                }
            }
     
            public string Category
            {
                get
                {
                    return this._category;
                }
                set
                {
                    if (this._category != value)
                    {
                        this._category = value;
                    }
                }
            }
     
            public decimal Value
            {
                get
                {
                    return this._value;
                }
                set
                {
                    if (this._value != value)
                    {
                        this._value = value;
                    }
                }
            }
        }

    I borrowed dynamic chart method in telerik's sample and  just only add to create series in ViewModel instead of code behind.

    RGDS

    Kang

Back to Top