Live data chart panning issues

5 posts, 0 answers
  1. Andrey
    Andrey avatar
    1 posts
    Member since:
    Jul 2012

    Posted 23 Jul 2012 Link to this post

    Hi, I am currently working over the chart control which should fulfill the following requirements:

    • represent live linear charts (like a processor load chart)
    • provide multiple y-axis (to represent charts of boolean, integer and double variables on the same x-axis)
    • provide panning by x-axis ability

    I checked if your RadChartView control was able to deal with this task and fell in trouble with several issues. I hope that reasons for such a behavior come from my lack of understanding how charting should be implemented, so we will be able to rely on your control if only we would have those issues fixed. Instead of attaching the whole project, I will try to provide enough information for you in the code snippets.

    I need to show from 1 to 10 parameters of different types.

    When each parameter is updated i add new value in the corresponding array this way: 


    ParameterInfo._log.Add(val, DateTime.Now);


    public class ParameterRecord
    {
      private object _value;
      private DateTime _date;
    }
      
    public class ParameterInfo : ViewModelBase
    {
      private ObservableCollection<ParameterRecord> _log;
      private string _type;
    }

    The first problem is

    'How can I provide simple x-axis panning capabilities for the live chart?'

    I have a timer which updates the chart each 500 milliseconds. It basically fixes the Maximum and Minimum properties of the x-axis:

    chart.HorizontalAxis.Minimum = now.Subtract(_horizontalScaleLength);
    chart.HorizontalAxis.Maximum = now;

    In this way the auto-pan to the last moment works alright but there's no possibility to pan the chart. 

    It's obvious that if I want to provide the panning to the very initial moment when the chart was shown, I shall leave 


    chart.HorizontalAxis.Minimum == initialDateTime;

    I see two possibilities to fix this issue:

    1. Use the external scrollbar and bind it to HorizontalAxis.Minimum and HorizontalAxis.Minimum properties. Activate user-driven panning when the scrollbar changes its value, switch back to auto-panning when, for example, user sets the maximum value on the scrollbar. Unfortunately this won't look good enough if I will use the external scrollbar. Is it possible to customize the behavior of the internal scrollbar to satisfy our needs?
    2. Every time the chart should be updated (500 milliseconds in my case) leave all the parameters unchanged except the zoom scale. Theoretically it's possible to calculate the appropriate zoom value so the absolute size of the visible segment on the x-scale would be constant. However I couldn't find available property via which I could change the zoom scale dynamically from the code behind. Is there any possibility?


    The second problem is

    'How much points should i add to the data source? How much points is it able to carry?'


    At first I tried to add the values every time the timer event is figured (i.e. each 500 milliseconds) However it turned out to be a bad idea. The chart started to go slower and almost stopped with the time. It had about 5000 data points just for 1 minute. I suppose that either there shouldn't be very much points in the data source or I should dynamically filter only the visible segment of a big array. Do you see the latter way convenient enough?

    So I turned to the other option, I added new data points to the appropriate series only when their values change. Unsurprisingly, the result looked like a saw (attached file telerik letter - zig-zag trackball.gif)

    So I had to add two values when the new value arrives and move the second one further to prolongate the horizontal segment until the next change:

    if (oldValue != newValue)
    {
      lg.Add(new ParameterRecord(newValue, DateTime.Now)); // the point that will remain
      lg.Add(new ParameterRecord(newValue, DateTime.Now)); // the point that will be prolongated
    }
    else
    {
      lg.RemoveAt(lg.Count - 1);
      lg.Add(new ParameterRecord(oldValue, DateTime.Now));   // prolongate the horizontal line
    }

    I want you to know if this is a convenient way because it leads to the problem with the TrackBallInfo. Because there are no data points, in between the moments of the value change, the TrackBallInfo snaps to the closest data point instead of displaying the actual value under the mouse pointer. This is not desired (look at the attachment telerik letter - trackball glitch.gif) 

    I also have troubles with the dynamical setting of the bunch of y-axes in the code behind, but I didn't try enough by myself yet because it's crucial to know if Telerik's solution is able to deal with just the issues described here.

    Thank you,

    Andrey

  2. Ryan
    Ryan avatar
    2 posts
    Member since:
    Aug 2012

    Posted 23 Jul 2012 Link to this post

    Hi Andrey ,
    I don't want to hijack your thread, but I'm also struggling with a similar problem. I'm also implementing a chart with multiple Y - Axes. However I have not been able to programmatically / dynamically add the Y - Axes in the code behind. I can only achieve this by hard coding the xaml. Whenever I try to reference the VerticalAxis property of the series I am adding, I get an error saying that it hasn't been set to an instance of an object.

    EDIT: It was simpler than I thought. I had to create an instance of the vertical axis and assign it to the series I was adding to the chart.

    LineSeries series = new LineSeries();
    series.ValueBinding = new PropertyNameDataPointBinding("Value");
    LinearAxis ax = new LinearAxis();
    ax.Title = "MyAxis";
    series.VerticalAxis = ax;
  3. UI for WPF is Visual Studio 2017 Ready
  4. Yavor
    Admin
    Yavor avatar
    401 posts

    Posted 26 Jul 2012 Link to this post

    Hello Andrey,

    1) You can try using RadChartView PanAndZoom behavior. It can be configured to allow zooming and panning only on the X-axis. Here is some xaml:

    <telerik:RadCartesianChart.Behaviors>
        <telerik:ChartPanAndZoomBehavior PanMode="Horizontal" ZoomMode="Horizontal" />
    </telerik:RadCartesianChart.Behaviors>
    You can find more information in this topic in our help system.

    I have prepared for you a small application that displays some live data from a timer on every 500 ms and using this behavior.

    2)
    The answer to that question is: It depends. As a rule of a thumb, the more the datapoints, the slower the graph. In your live data scenario you can try zooming to a smaller interval window using the pan and zoom described above and when the data comes you will observe only a small amount of it and the performance will be better. If you want to see more points though, then you can try date sampling in order to reduce the number of visual items. Sampling in ChartView is supported through a control called ChartDataSource. Here you can find more information on it.

    Greetings,
    Yavor
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  5. Yavor
    Admin
    Yavor avatar
    401 posts

    Posted 26 Jul 2012 Link to this post

    Hi Ryan,

    Additional axes can be added to series in code behind with no problem. Just remember, that the primary axes of the chart (those set on the RadCartesianChart directly) are shared automatically between all series that don't have additional axes specified on them and you don't have to set them again. Only set axes on series you need additional axes on.

    Greetings,
    Yavor
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  6. Ryan
    Ryan avatar
    2 posts
    Member since:
    Aug 2012

    Posted 07 Aug 2012 Link to this post

    Thanks for the support!
Back to Top
UI for WPF is Visual Studio 2017 Ready