EKG signal using RadChartView

5 posts, 1 answers
  1. Hu
    Hu avatar
    9 posts
    Member since:
    May 2020

    Posted 28 May 2020 Link to this post

    Hello,

     

    The sample 955167-RadChartViewLiveData shows a way to display Live Data using the RadChartView. In this scenario the data points moves from right to left.

    I'm looking for show an EKG signal (of one channel) using the RadChartView control. The required features are:

    • When new data point arrived, it must be added without moving all the points. Just deleted the point in the right side of last point added.
    • A "white box" after the last point must be showed, to indicate progress. The EKG chart attached shows a degrade which is not required.

    Please, may I know a suggested approach to obtain similar results?

    Thanks

  2. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    4131 posts

    Posted 01 Jun 2020 Link to this post

    Hello, Hu,  

    According to the provided information, I suppose that you are referring to this forum thread: https://www.telerik.com/forums/chartview-and-real-time-data 

    The demonstrated example for live data moves the line from right to left, because the first data point (on the left side) is removed and a new data point is added (on the right side). Since the date axis is chronological, the newly added data point has a category with the respective DateTime.

    RadChartView supports empty values in the series. In general empty values means missing Y value for a particular X value. This is appropriate for achieving blank parts within the chart. Additional information about the null values support is available in the following help article: https://docs.telerik.com/devtools/winforms/controls/chartview/null-values-support- 

    I have prepared a sample project for your reference which result is illustrated in the attached gif file: 
            Random rnd = new Random();
            FastLineSeries series = new FastLineSeries();
            Dictionary<string, double?> categoryValuePairs = new Dictionary<string, double?>();
            public RadForm1()
            {
                InitializeComponent();                  
                
                for (int i = 0; i < 100; i++)
                {
                    CategoricalDataPoint point = new CategoricalDataPoint(rnd.Next(50, 100), i);
                    series.DataPoints.Add(point); 
                    categoryValuePairs.Add(i.ToString(),point.Value);
                }
                radChartView1.Series.Add(series);
                CategoricalAxis categoricalAxis = series.HorizontalAxis as CategoricalAxis; 
                categoricalAxis.LabelFitMode = AxisLabelFitMode.Rotate;
                this.timer1.Interval = 100;
            }
    
            private void radButton1_Click(object sender, EventArgs e)
            {
                if (!this.timer1.Enabled)
                {
                    this.timer1.Start();
                }
                else
                { 
                    this.timer1.Stop();
                }
            }
    
            int cnt = 0;
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                cnt++;
                if (cnt >= series.DataPoints.Count - 5)
                {
                    cnt = 0;
                }
                CategoricalDataPoint point = null;
                for (int i = 0; i < series.DataPoints.Count; i++)
                {
                    point = (CategoricalDataPoint)series.DataPoints[i];
                    if (i >= cnt && i < cnt + 5)
                    {
                        point.Value = null;
                    }
                    else
                    {
                        point.Value = categoryValuePairs[point.Category.ToString()];
                    }
                }
            }

    I hope this information helps. If you need any further assistance please don't hesitate to contact me. 

    Regards,
    Dess | Tech Support Engineer, Sr.
    Progress Telerik

    Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
    Our thoughts here at Progress are with those affected by the outbreak.
  3. Hu
    Hu avatar
    9 posts
    Member since:
    May 2020

    Posted 01 Jun 2020 Link to this post

    Dear Dess,

    Thanks for your feedback and sample project. Appreciated.

     

    A User Control was implemented based on your project a some minors changes. 

    Three (3) testing scenarios were performed as described below:

    • 100 points adding one (1) value/sample with a timer from the Main Form @10ms.
    • 1000 points adding one (1) value/sample with a timer from the Main Form @10ms.
    • 10000 points adding 100 value/sample with a timer from the Main Form @1ms. I also adjusted the ramp increment/decrement value.

    Attached some videos (gif) of the testing as well.

    Our goal is to have real time chart that could manage to add from 1 to 100 new points at the same time, and keep in the screen 10.000 points. Considering this request, may you suggest an approach to improve the performance?

     

    Thanks for your attention

    Hu

    public partial class UserControlRealTimeBarChartView : UserControl
        {
            Random rnd = new Random();
            FastLineSeries series = new FastLineSeries();
            Dictionary<string, double?> categoryValuePairs = new Dictionary<string, double?>();
            public UserControlRealTimeBarChartView()
            {
                InitializeComponent();
                for (int i = 0; i < 10000; i++)
                {
                    CategoricalDataPoint point = new CategoricalDataPoint(0, i);
                    series.DataPoints.Add(point);
                    categoryValuePairs.Add(i.ToString(), point.Value);
                }
                radChartView1.Series.Add(series);
                LinearAxis axeY = radChartView1.Axes.Get<LinearAxis>(1);
                axeY.Minimum = -50;
                axeY.Maximum = 50;
                axeY.ClipLabels = false;
                axeY.ShowLabels = false;
                axeY.LineWidth = 0;
                axeY.TickWidth = 0;
                CategoricalAxis axeX = radChartView1.Axes.Get<CategoricalAxis>(0);
                axeX.ClipLabels = false;
                axeX.ShowLabels = false;
                axeX.LineWidth = 0;
                axeX.TickWidth = 0;
                radChartView1.View.MinSize = new SizeF(0F, 0F);
                radChartView1.View.Padding = new Padding(0, 0, 0, 0);
                radChartView1.View.Margin = new Padding(0, 0, 0, 0);
            }
            int cnt = 0;
            double ramp = 0;
            bool direction = false;
            public void AddSample()
            {
                categoryValuePairs[cnt.ToString()] = ramp;
                if (direction)
                {
                    ramp+=0.03;
                    if (ramp >= 30)
                        direction = false;
                }
                else
                {
                    ramp-=0.03;
                    if (ramp <= -30)
                        direction = true;
                }
                cnt++;
                if (cnt >= series.DataPoints.Count)
                {
                    cnt = 0;
                }
                CategoricalDataPoint point = null;
                for (int i = 0; i < series.DataPoints.Count; i++)
                {
                    point = (CategoricalDataPoint)series.DataPoints[i];
                    if (i >= cnt && i < cnt + 5)
                    {
                        point.Value = null;
                    }
                    else
                    {
                        point.Value = categoryValuePairs[point.Category.ToString()];
                    }
                }
            }
        }
  4. Answer
    Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    4131 posts

    Posted 03 Jun 2020 Link to this post

    Hello, Hu, 

    The provided gif files are greatly appreciated. 

    To be honest, 10 000 data points are quite much for RadChartView. It is not even possible to see so many points at the screen simultaneously. It is expected to affect the performance when it has to draw so many points. 

    In order to improve performance, you can perform some grouping operation in your data before attaching it to RadChartView. Another solution is to aggregate the data - that is, reduce it to a smaller number of points by 'combining' values by taking their averages.

    For example you can have 50,000 points. If you average every 10 values, the number of points is reduced to 5000. That is still too many, so you could average, say, in blocks of 100 or even 250. Alternatively, aggregate a previous aggregate - with, say, 10 values in each takes you down from 50,000 to 5000 to 500. Thus, RadChartView will manage fewer data and it will be fast enough.

    If you refer to our Demo application >> ChartView >> Live Data example, you will notice that the chart uses a fixed number of data points. Each second the first data point is removed and a new one is added. Thus, the chart will be "light" enough for rendering.

    Should you have further questions please let me know.

    Regards,
    Dess | Tech Support Engineer, Sr.
    Progress Telerik

    Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
    Our thoughts here at Progress are with those affected by the outbreak.
  5. Hu
    Hu avatar
    9 posts
    Member since:
    May 2020

    Posted 09 Jun 2020 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    Dear Dess,

    Thanks again for your feedback. 

    I was able decrease the quantity of the points (for now) and remove samples as you suggested at the end of your message. 

    Regards

     

Back to Top