Doughnut Series: ObservableCollection change is not shown

Hello!

I'm having trouble getting my Doughnut Chart to recognize changes to the ObservableCollection<Object> (e.g. when the whole Collection gets cleared and newly set).
I've used the INotifyPropertyChanged, but it seems that this is not the right choice since it only listen to the Objects's variables.
Any suggested way to implement changes to the element of the ObservableCollection?

My current code looks like this:

Portfolio.xaml.cs:

using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Collections.ObjectModel;
using Exchanges.Models.UI;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Collections.Specialized;

namespace CryptoSuite.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Portfolio : ContentPage, INotifyPropertyChanged
    { 
        private ObservableCollection<BalanceUI> balanceList;
        public ObservableCollection<BalanceUI> BalanceList
        {
            get { return balanceList; }
            set
            {
                this.balanceList = value;
                RaiseBalanceListChanged("BalanceList");
            }
        }
        public Portfolio()
        {
            InitializeComponent();
            //BindingContext = App.handler;
            BalanceList = new ObservableCollection<BalanceUI>();
            var balance1 = new BalanceUI(5.0m, "Test", 0.01m, "Test");
            var balance2 = new BalanceUI(10.0m, "Test2", 1000.0m, "Test");
            BalanceList.Add(balance1);
            BalanceList.Add(balance2);
            BindingContext = this;
            Task.Run(async () =>
            {
                await ChangeDataTest();
            });
        }
        public async Task ChangeDataTest()
        {
            #region Test-Data
await Task.Delay(7000);
            var temp = new ObservableCollection<BalanceUI>();
            var balance3 = new BalanceUI(1.0m, "Test3", 10.0m, "Test");
            var balance4 = new BalanceUI(2.0m, "Test4", 10.0m, "Test");
            temp.Add(balance3);
            temp.Add(balance4);
BalanceList.Clear();
            BalanceList = temp;
            #endregion
        }
        public event PropertyChangedEventHandler BalanceListChanged;
        void RaiseBalanceListChanged(string propertyName)
        {
            if(BalanceListChanged != null)
                BalanceListChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Portfolio.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:chart="clr-namespace:Syncfusion.SfChart.XForms;assembly=Syncfusion.SfChart.XForms"
             x:Class="CryptoSuite.Views.Portfolio">
    <ContentPage.Content>
        <StackLayout x:Name="Stack">
            <chart:SfChart x:Name="Chart" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
                <chart:SfChart.Legend>
                    <chart:ChartLegend IconHeight="14" IconWidth="14" OverflowMode="Wrap" DockPosition="Bottom" />
                </chart:SfChart.Legend>
                <chart:SfChart.Series>
                    <chart:DoughnutSeries x:Name="Nut" ListenPropertyChange="True" CircularCoefficient="0.80" ItemsSource="{Binding BalanceList, UpdateSourceEventName=BalanceListChanged}" XBindingPath="currency" YBindingPath="fia_balance" ExplodeOnTouch="True" LegendIcon="Circle" EnableAnimation="true" StrokeWidth="0" StrokeColor="Black">
                        <chart:DoughnutSeries.DataMarker>
                            <chart:ChartDataMarker LabelContent="YValue"  ShowLabel="True" MarkerColor="Black">
                            </chart:ChartDataMarker>
                        </chart:DoughnutSeries.DataMarker>
                        <chart:DoughnutSeries.ColorModel>
                            <chart:ChartColorModel Palette="Metro" />
                        </chart:DoughnutSeries.ColorModel>
                    </chart:DoughnutSeries>
                </chart:SfChart.Series>
            </chart:SfChart>
    </StackLayout>
    </ContentPage.Content>
</ContentPage>

Thanks in advance for your help.

Alexander


5 Replies

LA Lavanya Anaimuthu Syncfusion Team June 26, 2018 01:23 PM UTC

  
Hi Alexander, 
  
Thanks for using Syncfusion products.    
  
We have analyzed your query, and we suspect that you are declared a custom  BalanceListChanged event. We have changed the default PropertyChanged event instance of the custom event from INotifyPropertyChanged interface. Your codes are working fine with the simple sample.  
 
Code snippet [C#]:   
       
        private ObservableCollection<Model> data; 
        public ObservableCollection<Model> Data 
        { 
            get 
            { 
                return data; 
            } 
            set 
            { 
                data = value; 
                RaiseBalanceListChanged("Data"); 
            } 
        } 
      public event PropertyChangedEventHandler PropertyChanged; 
      void RaiseBalanceListChanged(string propertyName) 
      { 
            if (PropertyChanged != null) 
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
 
  
  
Can you please check with the sample in the following location? If still you face the problem, please revert us by modifying the sample based on your application along with replication procedure. This would be helpful for us to serve you.  
  
 
  
Regards,  
Lavanya Anaimuthu.  



AL Alexander June 27, 2018 09:16 AM UTC

Hi Lavanya Anaimuthu,

thanks for your answer.
I didn't know, that 'PropertyChanged'  is inherited. I changed the event name from BalanceListChanged to PropertyChanged and it worked.
However I have struggles getting this to work in my whole Project.
I simplified my project with all necessary files and attached it.

What I'm currently doing, is that I have a global data handler (instanciated at App.xaml.cs), which is accessable from all pages.
Portfolio.xaml is a children of my (Tabbed) MainPage.
None of the changes I do to my testdata (@DataHandler) is shown in the Chart.

Thanks in advance.
Alexander

Attachment: CryptoSuiteSimple_82e536cf.7z


MK Muneesh Kumar G Syncfusion Team June 29, 2018 01:59 PM UTC

Hi Alexander,  
 
We have resolved the data update problem by adding data in thread as per the below code snippet.  
 
Code snippet [C#]: 
Task.Delay(7000).Wait(); 
            Device.BeginInvokeOnMainThread(() => 
            { 
                BalanceList.Add(balance3); 
            }); 
 
Task.Delay(5000).Wait(); 
            Device.BeginInvokeOnMainThread(() => 
            { 
                BalanceList.Clear(); 
                BalanceList = temp; 
            }); 
 
Also, we could have found that INotifyPropertyChanged not implemented in DataHandler by implementation this, the sample is running without any problem. Please find the modified sample under the following location.  
 
 
Please let us know if you have any queries.  
 
Thanks, 
Muneesh Kumar G. 
 



AL Alexander June 29, 2018 04:22 PM UTC

Thanks alot, works like a charm now! :)


/edit: One last question. I've implemented an Selection Event for the Doughnut Chart with the following code:

void OnBalanceSelected(object sender, ChartSelectionEventArgs args)
{
     //Open in new page
    Navigation.PushAsync(new PortfolioDetail(App.handler.BalanceList[args.SelectedDataPointIndex]));
    //Deselecting
    DoughnutChart.SelectedDataPointIndex = -1;
    DoughnutChart.ExplodeIndex = -1;
}

Push-opening the new page with the right Object works fine, however the deselection somehow doesn't work.
Setting the ExplodeIndex to -1 works, the explosion is undone, however setting the DataPointIndex to -1 is not working, the Object is still selected after returning to the Chart-Page.


MP Michael Prabhu M Syncfusion Team July 2, 2018 10:48 AM UTC

Hi Alexander, 
 
We have reviewed your code and found that you are using SelectionChanged event to navigate to a new page but instead of this event you can hook SelectionChanging event which will trigger while the selection is in process and you can set e.Cancel = true so that the selection will not process further and the selection color will not be applied to the segment. 
 
Based on this we have modified the code and you can find the code snippet below. 
Code snippet [XAML]:   
<SfChart x:Name="chart" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" SelectionChanging="Chart_SelectionChanging"> 
 
  
Code snippet [C#]:    
async void Chart_SelectionChanging(object sender, ChartSelectionChangingEventArgs e) 
  { 
     e.Cancel = true; 
     Navigation.PushAsync(new PortfolioDetail(App.handler.BalanceList[args.SelectedDataPointIndex]));                            
   DoughnutChart.ExplodeIndex = -1; 
} 
 
  
Let us know if you require further assistance on this. 
 
Thanks, 
Michael 


Loader.
Up arrow icon