When ActualRange gets initialized

8 posts, 1 answers
  1. Lian
    Lian avatar
    12 posts
    Member since:
    Jan 2015

    Posted 27 Jan 2015 Link to this post

    I am using the latest version of RadCartesianChart.
    In my application, the chart has a LinerAxis (AutoRange) as vertical axis and it works very well.

    Now I am going to add annotation to the chart programmatically at the beginning. So an event handler was created to handle chart's Loaded event, and then the annotation accesses the ActualRange in the event handler by using the below code: 

    var vAxis = (LinearAxis)chart.VerticalAxis;
    annotation.VerticalValue = vAxis.ActualRange.Maximum;

    But unfortunately in this scenario, it seems the ActualRange doesn't get initialized and returns zero as result.
    Could you please show me which chart event needs to be hooked, in order to get the ActualRange? Many thanks.
  2. Lian
    Lian avatar
    12 posts
    Member since:
    Jan 2015

    Posted 27 Jan 2015 in reply to Lian Link to this post

    Additionally, with Loaded event handler, the method ConvertDataToPoint doesn't work as expected, the calculated point gets NaN as x coordinate value.
  3. UI for WPF is Visual Studio 2017 Ready
  4. Lian
    Lian avatar
    12 posts
    Member since:
    Jan 2015

    Posted 27 Jan 2015 Link to this post

    I tried to add annotation in the vertical axis's ActualRangeChanged event handler (because the size and location of annotation need to be calculated by vertical axis ActualRange and DataPoints), then ActualRange and ConvertDataToPoint all work fine but an exception is thrown as attached.
  5. Answer
    Petar Marchev
    Admin
    Petar Marchev avatar
    968 posts

    Posted 28 Jan 2015 Link to this post

    Hello,

    I will try to answer all of your questions in the order they appeared.

    in this scenario, it seems the ActualRange doesn't get initialized and returns zero
    The ActualRange may not be ready in the loaded event for some reasons, perhaps the chart is not yet data bound and there are no data points. If there are no data points - the axis cannot possible select an actual range, the actual range is not yet known. The proper event is the ActualRangeChanged event, as you have already discovered.

    Additionally, with Loaded event handler, the method ConvertDataToPoint doesn't work as expected, the calculated point gets NaN as x coordinate value.
    The conversion methods rely on a valid actual range and valid layout. If at the moment you used the convert method the actual range was not yet ready - this is why you get these results, the actual range is not yet known and the convert method cannot possibly do the calculations.

    I tried to add annotation in the vertical axis's ActualRangeChanged event handler ... but an exception is thrown ...
    It seems that you have stumbled upon a bug in the control
    . I have logged this in our feedback portal where you can vote and track its status. I have also updated your Telerik points. A simple way to work-around this is to wrap the code in a BeginInvoke:
    private void LinearAxis_ActualRangeChanged(object sender, Telerik.Charting.NumericalRangeChangedEventArgs e)
    {
     this.Dispatcher.BeginInvoke((Action)(() =>
     {
      this.chart1.Annotations.Add(new CartesianCustomAnnotation());
     }));
    }

    I just want to make sure that you actually need the event to add the annotation. Does the position of the annotation rely on the actual range of the axis? If not, perhaps you should not use the event at all and add the annotations earlier. Let us know if you need more information.

    Regards,
    Petar Marchev
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  6. Lian
    Lian avatar
    12 posts
    Member since:
    Jan 2015

    Posted 28 Jan 2015 in reply to Petar Marchev Link to this post

    Thank you Petar. I will try your solution tomorrow and tell you the results.

    The reason why I have to set up annotation in the ActualRangeChanged event, is as you said, the annotation relies the actual range of vertical axis.

    There is the requirement: Show the track-info of last DataPoint programmatically after the UserControl is loaded. 

    Then I did some investigation the track-info behavior doesn't support it at all. as you mentioned 2 years ago:
    http://www.telerik.com/forums/sync-trackball-move-on-two-charts
    "The track-info behavior is designed to work much as a tool-tip. It reacts only when the mouse is over the chart. Thus you can not start it with code, it will only display if the mouse is on top of the chart. So, unfortunately you can not achieve this programatically."

    So after checked the ChartUtilities of SDK example, I decided to implement an annotation that looks like the track-info.
      - Our chart contains 2 SplineSeries with different DataPoint counts. So the last DataPoint should be the DatePoint which has larger x-coordinate value in the range of all DataPoints - I use the method ConvertDataToPoint to convert the last DataPoints of all SplineSeries into coordinate points and then compare their x-coordinate values. 
      - The vertical value of info panel is set to vAxis.ActualRange.Maximum, in order to arrange the info panel to the top of chart

    What do you think about my workaround solution? Is there any easier approach to achieve the target?

  7. Petar Marchev
    Admin
    Petar Marchev avatar
    968 posts

    Posted 28 Jan 2015 Link to this post

    Hello Lian,

    Actually we have already improved the track-ball behavior to allow the behavior shown in the track-ball-like annotations sample. The new functionality and new sdk sample will be available with the next official release, end of February.

    As for the work-around that you explained, I do not understand why you need to use the conversion api at all. You can simply get the actual data item (from the DataItem) property and see if it has the largest value. You may need to do this only for the last point of each series, given that the items in the ItemsSource are ordered. You can also get directly the layout slot of the data point, allowing you to see which data point is on the most right.

    If you need this annotation to be visible at all times (meaning that it is not part of the moving track-ball display) you can easily create properties in the view models. In the view models you can see which item is to the most right (which item has the largest date). So you can set the two properties in the view model and you can add an annotation in xaml and bind it to these properties.

    Let me know if you need more information.

    Regards,
    Petar Marchev
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  8. Lian
    Lian avatar
    12 posts
    Member since:
    Jan 2015

    Posted 29 Jan 2015 in reply to Petar Marchev Link to this post

    Hi Petar,

    Thanks for your workaround solution, it does cope with ActualRangeChanged event handler and prevent the exception.

    Why I need to use the conversion api?
    I implemented the track-info-style annotation as the wpf behavior for purpose of reusable.
      - An attached property is set to chart in xaml
      - In the property changed callback method, the chart registers Loaded event
      - In Loaded event handler, vertical axis registers ActualRangeChanged event
      - In ActualRangeChanged event handler, with the calculated most right horizontal value and maximum vertical value, 2 annotation objects are added to chart programatically
    Hence, by using the conversion api, the comparison method can adapt to different data source types for different chart instances.

    Why I didn't set the annotation in xaml?
    I agree, by binding to view model properties, it's easy to get the the most right data item. But at the meantime, there are new problems:
    1. Unfortunately the annotation needs to be hidden once the real track-info is triggered by mouse-over action
     It's not a big deal, I can set up the visibility of annotation in the TrackInfoUpdated event handler
    2. Get the vertical range maximum value as custom annotation's vertical value
    The track-info panel annotation is used to show the values of current "focused" data points and it is located at the top of chart.
    The vertical axis's ActualRangeChanged event handler eases the access to vertical range.
    The problem is - how does annotation access the chart's vertical range in xaml?

    One more question about the chart trackball behaviour - does it support touch screen and touch events (Business Requirement!) ?
    So far I didn't get chance to try my application in a real touch screen, but I really hope your answer is YES ;p
    Otherwise, I have to re-invent the "wheel" with the touch events, crazy!

    Many thanks,
    Lian

  9. Petar Marchev
    Admin
    Petar Marchev avatar
    968 posts

    Posted 29 Jan 2015 Link to this post

    Hello Lian,

    Thank you for the detailed explanations. We are happy that you have thought things so well and developed a nice interactive chart.

    Yes, the trackball should work without any additional effort on a touch device, we have internal code that handles this.

    Regards,
    Petar Marchev
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
Back to Top
UI for WPF is Visual Studio 2017 Ready