RadCartesianChart inside RadBusyIndicator on iOS

7 posts, 1 answers
  1. VPS
    VPS avatar
    30 posts
    Member since:
    Jan 2015

    Posted 19 Jan 2018 Link to this post

    I have a RadCartesianChart that needs to be updated regularly from a REST api, so I have placed the chart (and a few other controls) inside a RadBusyIndicator. When the data gets updated, the busy indicator shows and stays on for while updating the data, but when the busy indicator should go away and show the chart it throws an exception. This behaviour only happens on iOS, on Android and UWP it all goes as expected: no exception and the page is shown.

    The details of the exception are:

    {System.ObjectDisposedException: Cannot access a disposed object.
    Object name: 'TKExtendedChart'.
      at Foundation.NSObject.get_SuperHandle () [0x00015] in /Users/builder/data/lanes/5665/f70a1348/source/xamarin-macios/src/Foundation/NSObject2.cs:416 
      at TelerikUI.TKChart.get_WeakDataSource () [0x00025] in <5bae2bad360b4d5da328902516ddda38>:0 
      at TelerikUI.TKChart.get_DataSource () [0x00000] in <5bae2bad360b4d5da328902516ddda38>:0 
      at Telerik.XamarinForms.ChartRenderer.iOS.ChartSeriesAdapter`2[S,T].UpdateItemsSource (S sourceOwner, T targetOwner, TelerikUI.TKChart targetChart) [0x00006] in <7703bf205c0d44fb9c68eb78a97e22de>:0 
      at Telerik.XamarinForms.ChartRenderer.iOS.ChartSeriesAdapter`2[S,T].UpdateSeriesProperties (System.String propertyName, S sourceOwner, T targetOwner, Telerik.XamarinForms.Chart.RadChartBase sourceChart, TelerikUI.TKChart targetChart) [0x00080] in <7703bf205c0d44fb9c68eb78a97e22de>:0 
      at Telerik.XamarinForms.ChartRenderer.iOS.CategoricalSeriesAdapter`1[TSeries].UpdateSeriesProperties (System.String propertyName, TSeries sourceOwner, TelerikUI.TKChartSeries targetOwner, Telerik.XamarinForms.Chart.RadChartBase sourceChart, TelerikUI.TKChart targetChart) [0x00000] in <7703bf205c0d44fb9c68eb78a97e22de>:0 
      at Telerik.XamarinForms.ChartRenderer.iOS.BarSeriesAdapter.UpdateSeriesProperties (System.String propertyName, Telerik.XamarinForms.Chart.BarSeries sourceOwner, TelerikUI.TKChartSeries targetOwner, Telerik.XamarinForms.Chart.RadChartBase sourceChart, TelerikUI.TKChart targetChart) [0x00000] in <7703bf205c0d44fb9c68eb78a97e22de>:0 
      at Telerik.XamarinForms.ChartRenderer.iOS.ChartSeriesAdapter`2[S,T].UpdateCore (S sourceOwner, T targetOwner, System.String propertyName, Telerik.XamarinForms.Common.IParentElement sourceOwnerRoot, System.Object targetOwnerRoot) [0x00015] in <7703bf205c0d44fb9c68eb78a97e22de>:0 
      at Telerik.XamarinForms.Chart.ChartElementFacadeAdapter`2[S,T].Update (System.Object sourceOwner, System.Object targetOwner, System.String propertyName, System.Object sourceOwnerRoot, System.Object targetOwnerRoot) [0x00000] in <7703bf205c0d44fb9c68eb78a97e22de>:0 
      at Telerik.XamarinForms.Common.XamarinToNativeControlExtensions.Update[T,K] (T nativeElement, K xfЕlement, System.String propertyName, System.Object sourceOwnerRoot, System.Object targetOwnerRoot) [0x00031] in <be10754fe83d4f30b3bf0368f5628901>:0 
      at Telerik.XamarinForms.Chart.ChartElement.OnPropertyChanged (System.String propertyName) [0x00025] in <7703bf205c0d44fb9c68eb78a97e22de>:0 
      at Xamarin.Forms.BindableObject.SetValueActual (Xamarin.Forms.BindableProperty property, Xamarin.Forms.BindableObject+BindablePropertyContext context, System.Object value, System.Boolean currentlyApplying, Xamarin.Forms.Internals.SetValueFlags attributes, System.Boolean silent) [0x00107] in D:\agent\_work\1\s\Xamarin.Forms.Core\BindableObject.cs:594 
      at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes, Xamarin.Forms.BindableObject+SetValuePrivateFlags privateAttributes) [0x0015b] in D:\agent\_work\1\s\Xamarin.Forms.Core\BindableObject.cs:391 
      at Xamarin.Forms.BindingExpression.ApplyCore (System.Object sourceObject, Xamarin.Forms.BindableObject target, Xamarin.Forms.BindableProperty property, System.Boolean fromTarget) [0x001f9] in D:\agent\_work\1\s\Xamarin.Forms.Core\BindingExpression.cs:174 
      at Xamarin.Forms.BindingExpression.Apply (System.Object sourceObject, Xamarin.Forms.BindableObject target, Xamarin.Forms.BindableProperty property) [0x0006b] in D:\agent\_work\1\s\Xamarin.Forms.Core\BindingExpression.cs:77 
      at Xamarin.Forms.Binding.Apply (System.Object newContext, Xamarin.Forms.BindableObject bindObj, Xamarin.Forms.BindableProperty targetProperty) [0x00042] in D:\agent\_work\1\s\Xamarin.Forms.Core\Binding.cs:126 
      at Xamarin.Forms.BindableObject.ApplyBindings (System.Boolean skipBindingContext) [0x0003b] in D:\agent\_work\1\s\Xamarin.Forms.Core\BindableObject.cs:422 
      at Xamarin.Forms.BindableObject.ApplyBindings () [0x00000] in D:\agent\_work\1\s\Xamarin.Forms.Core\BindableObject.cs:126 
     

  2. Petar Marchev
    Admin
    Petar Marchev avatar
    1029 posts

    Posted 24 Jan 2018 Link to this post

    Hi,

    We are sorry to hear that you are having problems with our controls. Especially with exceptions.

    I did try to replicate the scenario you describe, but I did not get an exception of any type. I am attaching the demo files for your reference. I tried navigating back and forth several times with the busy indicator being busy and being not busy. I suspect that the issue is more related to the ItemsSource and not so much to the busy indicator.

    Could you modify the sample so that we can reproduce the issue? Then we can investigate the origins of the issue and look for solutions.


    Regards,
    Petar Marchev
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. Petar Marchev
    Admin
    Petar Marchev avatar
    1029 posts

    Posted 25 Jan 2018 Link to this post

    Hi again,

    After investing more time into this, I was able to slightly modify the code I sent previously, and was able to reproduce the exception. The small change I made was to reset the ItemsSource of the chart when the IsBusy property of the indicator changes. At this point in its life cycle, the XF chart is trying to tell its iOS counterpart to update. However, at times the iOS counterpart has already been disposed and a new native control has not been assigned yet.

    You should be able to resolve this issue almost completely by not using the Content property of the busy indicator for the moment. Right now, the chart is the content of the busy indicator, and when the IsBusy changes, the chart is added to and removed from the visual tree. This results in a native control being created and disposed. If you do not use the Content of the busy indicator, but keep the chart underneath the busy indicator, and toggle its visibility, then native controls should not get recreated, thus bypass the issue.

    I have logged this in our feedback portal and updated your Telerik points as a thank you for helping us improve our products.

    Regards,
    Petar Marchev
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  4. VPS
    VPS avatar
    30 posts
    Member since:
    Jan 2015

    Posted 29 Jan 2018 Link to this post

    I have tried your suggestion of moving the chart outside the busy indicator with mixed results:

    • the UWP version works as expected;
    • in the Android version the chart looses its size constraints;
    • in the iOS version the chart does not update itself.

    I have included screenshots of all the platforms, the screenshots marked Today are before updating the chart contents, the screenshots marked Yesterday are after updating the chart.

    The area being updated in my application is not only a chart, it's a Grid with several controls, including a chart. Something like:

    <primitives:RadBusyIndicator Grid.Row="2" VerticalOptions="FillAndExpand"
                                 IsBusy="{Binding IsBusy}"
                                 AnimationContentHeightRequest="48"
                                 AnimationContentWidthRequest="48"
                                 AnimationContentColor="{StaticResource AccentColor}"
                                 AnimationType="Animation2">
        <primitives:RadBusyIndicator.Content>
        </primitives:RadBusyIndicator.Content>
    </primitives:RadBusyIndicator>
     
    <Grid Grid.Row="2" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
          IsVisible="{Binding IsBusy, Converter={StaticResource InverseBoolConverter}}">
     
        ...
         
        <chart:RadCartesianChart Grid.Row="2" VerticalOptions="FillAndExpand" Palette="{Binding Palette}">
            ...
            <chart:RadCartesianChart.Series>
                <chart:BarSeries ItemsSource="{Binding CurrentData}" PaletteMode="Series"
                                 CombineMode="Stack"
                                 CategoryBinding="Category" ValueBinding="Value"/>
            </chart:RadCartesianChart.Series>
        </chart:RadCartesianChart>
     
        ...
         
    </Grid>

     

    The Grid that comes after the busy indicator was originally inside the busy indicator content.

    The code that updates the chart is similar to:

    IsBusy = true;
    CurrentData.Clear();
    // get new data
     IsBusy = false;

     

    The data update is triggered by a pan gesture on the chart.

  5. Petar Marchev
    Admin
    Petar Marchev avatar
    1029 posts

    Posted 31 Jan 2018 Link to this post

    Hi,

    I regret to hear that you have hit an obstacle when applying the work-around I suggested. I was able to recreate a demo project based on the code you provided and I think you should be able to fully resolve both setbacks.

    In Android the chart probably doesn't position and size as expected due to a left-over when getting the content out of the busy indicator. I see that there is a Grid.Row="2" setting on the chart, is it possible that you do not have proper row definitions? I am attaching the xaml and cs file I tested with, and in my setup, the chart is sized properly. If you still cannot do it, I suggest you wrap the chart in a Grid with a background and see if the Grid is positioned and sized where you expect it to.

    In iOS you observed that the chart does not update itself. I was able to reproduce this quickly and after some debugging I can confirm that this is due to a bug in the control. This is due to an incorrect handling of the Reset collection changed action. I have logged this in our feedback portal. As a token of gratitude for letting us know of this issue, I have updated your Telerik points.

    One way to work-around this is to set a completely new items source, instead of clearing the old one and adding items to it. This is actually demonstrated in the attachment in the ButtonUpdate_Click method.

    I hope I was able to address all your concerns, let me know if you need more information.

    Regards,
    Petar Marchev
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  6. VPS
    VPS avatar
    30 posts
    Member since:
    Jan 2015

    Posted 01 Feb 2018 in reply to Petar Marchev Link to this post

    Thaks for you suggestions, the iOS version is now working.

    On Android the problem persists. I have placed the chart inside a grid with a color background, as you suggested. The grid size is correct, but the chart looses its size constraints when updated.

    This is the xaml for the chart:

    <Grid Grid.Row="2" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
          BackgroundColor="Yellow">
        <chart:RadCartesianChart Palette="{Binding Palette}"
                             VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
            <chart:RadCartesianChart.GestureRecognizers>
                <PanGestureRecognizer PanUpdated="OnChartPan"/>
            </chart:RadCartesianChart.GestureRecognizers>
            <chart:RadCartesianChart.HorizontalAxis>
                <chart:CategoricalAxis LabelFitMode="MultiLine" LabelFontSize="{StaticResource TinyTextSize}"/>
            </chart:RadCartesianChart.HorizontalAxis>
            <chart:RadCartesianChart.VerticalAxis>
                <chart:NumericalAxis Minimum="0" LabelFontSize="{StaticResource TinyTextSize}"/>
            </chart:RadCartesianChart.VerticalAxis>
            <chart:RadCartesianChart.Grid>
                <chart:CartesianChartGrid MajorLinesVisibility="Y" StripLinesVisibility="None"/>
            </chart:RadCartesianChart.Grid>
            <chart:RadCartesianChart.Series>
                <chart:BarSeries ItemsSource="{Binding ChartData}" PaletteMode="Series" CombineMode="Stack"
                             CategoryBinding="Category" ValueBinding="Value"/>
                <chart:BarSeries ItemsSource="{Binding ChartData}" PaletteMode="Series" CombineMode="Stack"
                             CategoryBinding="Category" ValueBinding="Forecast"/>
            </chart:RadCartesianChart.Series>
        </chart:RadCartesianChart>
    </Grid>

     

    I have tried several options for the VerticalOptions and HorizontalOptions on the chart, including removing those options, but the result is always the same.

  7. Answer
    Petar Marchev
    Admin
    Petar Marchev avatar
    1029 posts

    Posted 02 Feb 2018 Link to this post

    Thank you for the attached code snippet. At first, I was not able to reproduce what you observe with the code you provided. However, after a discussion in the team, we realized that we actually hit this issue recently in our QSF in the Gauge example named Activity Dashboard.

    We stumbled upon this when migrating our examples to the new QSF. We seem to have worked around this by putting the chart in a Grid, setting two row definitions to the Grid, and setting row span of 2 for the chart:

    <Grid>
     <Grid.RowDefinitions>
      <RowDefinition Height="*" />
      <RowDefinition Height="*" />
     </Grid.RowDefinitions>
     <telerikChart:RadCartesianChart Grid.RowSpan="2">

    I know this is not ideal, but I hope that you will find it to be a feasible solution. I have logged a bug in our feedback portal where you can track its status. I have also updated your Telerik points as a thank you for helping us identify this problem. At this moment we are not sure what is causing this and we are not sure if the suggested work-around will work in your case, so do let us know if the row-span setting works, or if you need further assistance.

    Regards,
    Petar Marchev
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top