How to draw a real time line chart

11 posts, 1 answers
  1. James
    James avatar
    47 posts
    Member since:
    Jun 2009

    Posted 14 Sep 2009 Link to this post

    I need to draw a real time line chart with the following requirements:
    1. at first, the chart draws 60 plots. each plot represents one second in a minute
    2. at each second, the chart draws the line in the plot of the corresponding plot

    that is the chart draws the line gradually and the line for the past seconds would not occupy all the span of the chart space until 60 seconds past

    is this possible?
  2. James
    James avatar
    47 posts
    Member since:
    Jun 2009

    Posted 14 Sep 2009 Link to this post

    If above requirements are not possible, is there a way to control how the line is updated when ItemSource is updated? I use a ObservableCollection object as the chart's ItemSource and the collection is updated every seconds, now the chart redraws the whole line in it, but I want to make the line updated more smonthly by only updating the portion of the line on the newly added item in the collection
  3. Dwight
    Admin
    Dwight avatar
    475 posts

    Posted 17 Sep 2009 Link to this post

    Hi James,

    Currently such functionality is not supported. Functionality, that will help you achieve those requirements, is planned for release in the beginning of 2010.

    All the best,
    Evtim
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  4. James
    James avatar
    136 posts
    Member since:
    Nov 2008

    Posted 18 Oct 2009 Link to this post

    Hello,

    Does this mean it is not possible at the moment to implement real time charts at all, for example like the "CPU Usage History" in Windows Task Manager?

    This feature would be a fantastic feature for those of us who are developing finance related apps.

    Regards,

    James (different one from OP!)
  5. Dwight
    Admin
    Dwight avatar
    475 posts

    Posted 22 Oct 2009 Link to this post

    Hello James,

    It is possible to work around the problem by providing the RadChart with only the points that should be rendered. Out-of-the-box solution will be available for the Q1 2010 release.

    Best,
    Evtim
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  6. James
    James avatar
    136 posts
    Member since:
    Nov 2008

    Posted 22 Oct 2009 Link to this post

    OK great, thanks for the update. I look forward to the OOB functionality!

    Cheers,

    James.
  7. James
    James avatar
    47 posts
    Member since:
    Jun 2009

    Posted 25 Oct 2009 Link to this post

    hi Evtim

    >It is possible to work around the problem by providing the RadChart with only the points that should be rendered
    cannot wait till 2010. I'm interested the work around. Could you please give a sample? Thank you!

    James
  8. Answer
    Dwight
    Admin
    Dwight avatar
    475 posts

    Posted 28 Oct 2009 Link to this post

    Hi James,

    Here is a sample project (the XAML file only contains a RadChart with x:Name="radChart1").
    public partial class Page6 : UserControl
    {
        Random r = new Random();
        private ObservableCollection<CustomDataItem> source = new ObservableCollection<CustomDataItem>();
        private DispatcherTimer timer = new DispatcherTimer();
     
        public Page6()
        {
            InitializeComponent();
     
            this.radChart1.DefaultView.ChartArea.EnableAnimations = false;
            this.radChart1.DefaultView.ChartArea.AxisY.AutoRange = false;
            this.radChart1.DefaultView.ChartArea.AxisY.AddRange(0, 100, 20);
     
            timer.Interval = new TimeSpan(0, 0, 0, 1, 200);
            timer.Tick += TimerTick;
     
            SeriesMapping mapping = new SeriesMapping() { SeriesDefinition = new LineSeriesDefinition() };
            mapping.ItemMappings.Add(new ItemMapping() { FieldName = "Value", DataPointMember = DataPointMember.YValue });
            this.radChart1.SeriesMappings.Add(mapping);
            this.radChart1.ItemsSource = new TrimCollection<CustomDataItem>(this.source, 10);
     
            this.timer.Start();
        }
     
        private void TimerTick(object sender, EventArgs e)
        {
            this.source.Add(new CustomDataItem() { Value = r.Next(5, 100) });
        }
    }
     
    public class TrimCollection<T> : IEnumerable<T>, INotifyCollectionChanged
    {
        private int length = 10;
     
        public int Length
        {
            get { return this.length; }
            set
            {
                if (this.length != value)
                {
                    this.length = value;
                    this.UpdateCollection();
                }
            }
        }
     
        private ObservableCollection<T> source = null;
        private IEnumerable<T> trimmedSource;
     
        public TrimCollection(ObservableCollection<T> originalSource)
        {
            this.source = originalSource;
            this.source.CollectionChanged += OriginalSourceCollectionChanged;
        }
     
        public TrimCollection(ObservableCollection<T> originalSource, int length) : this(originalSource)
        {
            this.length = length;
        }
     
        public event NotifyCollectionChangedEventHandler CollectionChanged;
     
        public IEnumerator<T> GetEnumerator()
        {
            if (this.trimmedSource != null)
            {
                foreach (T item in this.trimmedSource)
                    yield return item;
            }
        }
     
        IEnumerator IEnumerable.GetEnumerator()
        {
            return (this as IEnumerable<T>).GetEnumerator();
        }
     
        private void UpdateCollection()
        {
            if (this.source == null)
                return;
     
            int trimLength = Math.Max(this.source.Count - this.Length, 0);
            this.trimmedSource = this.source.Skip(trimLength);
     
            if (this.CollectionChanged != null)
                this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }
     
        private void OriginalSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            this.UpdateCollection();
        }
    }
     
    public class CustomDataItem
    {
        public int Value { get; set; }
    }

    Note: The TrimCollection does the trick with trimming the original source to only the last N items.

    Best,
    Evtim
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  9. James
    James avatar
    47 posts
    Member since:
    Jun 2009

    Posted 22 Nov 2009 Link to this post

    Evtim

    Thanks a lot for the inspiring demo code!
  10. Grr
    Grr avatar
    9 posts
    Member since:
    Sep 2010

    Posted 02 Sep 2010 Link to this post

    Skip does not seems to be part of ObservableCollection<T>. Am I missing something here.
  11. Evgenia
    Admin
    Evgenia avatar
    1437 posts

    Posted 07 Sep 2010 Link to this post

    Hi Giri,

    Skip is extension method and it's part of System.Linq namespace. It's possible that you missed to add "using System.Linq".  For more information take a look at this http://social.msdn.microsoft.com/Search/en-us?query=system.linq+skip.

    Best wishes,
    Evgenia
    the Telerik team
    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 Public Issue Tracking system and vote to affect the priority of the items
Back to Top