Technology evolves rapidly and it’s becoming increasingly difficult to differentiate when to use what tool. This blog post seeks to assist you in making a decision between using a reporting solution and when to build custom views with a control suite in your application. We will begin by reviewing criteria that outlines the strengths of each solution and dive into an example scenario using a control suite. In part two of this series, we will dive into a scenario where using a Reporting solution is beneficial.

It’s no mystery that a reporting solution is built with the purpose of data visualization, printing/archiving and data sharing at its core. Control suites on the other hand are built with user experience and interactivity in mind. Control suites do deal with data presentment, but also deal with data entry.

Let’s begin with reviewing features that reporting solutions and control suites perform equally well.

  • Data mashing (the ability to display data from multiple data sources in a cohesive way)
  • Conditional formatting (the ability to change the appearance of data based on a specified condition)
  • Displaying hierarchical data
  • Display of data analysis and graphs
  • Crosstab/pivot data presentation

WHEN TO USE A CONTROL SUITE

Some of the features where applying a control suite would be beneficial are:

  • Data input (CRUD)
  • Paging of large data sets
  • Richer support for theming and customization
  • Live dashboard experience
  • Animation

WHEN TO USE A REPORTING SOLUTION

The following features are where a reporting solution shines:

  • Larger selection of export formats for offline consumption
  • Wide control over the printing process
  • Easier to layout data elements to achieve a desired look
  • Ability for an end user to create and edit reports
  • No additional code required for things like parameters, filtering, sorting (reporting deals with full data sets)
  • Cross technology compatibility – a single reporting implementation can be consumed on the web as well as in desktop technologies

Before deciding which solution to use, you need to answer these questions:

  • Do I need to provide data entry, live data or a rich UI to my users? If yes, use a control suite.
  • Do I need to print a whole [web] form or just a part of it? If the answer is “a whole form”, use reporting. If a part of it, then either solution will do.
  • Do I need to filter, sort and interact with the data and then print it? If yes, reporting is the way to go.
  • Will I allow my users to share the data they have mashed? If yes, reporting is probably the easier solution.

Have you been in the position to answer similar questions? If yes, please share your experience in the comments below – I would love to hear them!

A CONTROL SUITE SCENARIO – LIVE DATA

As mentioned above, it is best to use a control suite when you want to have real-time live data displays and dashboards. An example of a live data requirement can be a patient monitoring application. In this example, we used RadControls for WinForms to build a solution to demonstrate live updates of data into a RadChartView control. The control is responsible for displaying the heart rate and blood pressure values of a patient at 5 second intervals.

realtimeMonitoring

Figure 1 - A simulated real-time medical monitoring application

To implement this solution, first we will need to encapsulate the data being measured, a repository to retrieve the information from and lastly a Live Monitor that will access the repository for measurements every five seconds.

using System;

using System.ComponentModel;

using System.Linq;

using System.Threading;

 

namespace GridsAndReporting

{

    public class MedicalInfo : INotifyPropertyChanged

    {

        private DateTime _timeOfMeasurement;

        private int _heartRate;

        private int _systolicBloodPressure;

        private int _diastolicBloodPressure;

 

        public DateTime TimeOfMeasurement

        {

            get

            {

                return this ._timeOfMeasurement;

            }

            set

            {

                this ._timeOfMeasurement = value ;

                OnPropertyChanged( "TimeOfMeasurement" );

            }

        }

 

        public int HeartRate

        {

            get

            {

                return this ._heartRate;

            }

            set

            {

                this ._heartRate = value ;

                OnPropertyChanged( "HeartRate" );

            }

        }

 

        public int SystolicBloodPressure

        {

            get

            {

                return this ._systolicBloodPressure;

            }

            set

            {

                this ._systolicBloodPressure = value ;

                OnPropertyChanged( "SystolicBloodPressure" );

            }

        }

 

        public int DiastolicBloodPressure

        {

            get

            {

                return this ._diastolicBloodPressure;

            }

            set

            {

                this ._diastolicBloodPressure = value ;

                OnPropertyChanged( "DiastolicBloodPressure" );

            }

        }

 

        public event PropertyChangedEventHandler PropertyChanged;

 

        protected virtual void OnPropertyChanged( string propertyName)

        {

            if (PropertyChanged != null )

            {

                PropertyChanged( this , new PropertyChangedEventArgs (propertyName));

            }

        }

    }

 

    public class LiveMonitor : INotifyPropertyChanged

    {

        private BindingList < MedicalInfo > _data;

        private System.Windows.Forms. Timer _timer;

        private MedicalInfoRepository _repo = new MedicalInfoRepository ();

 

        public BindingList < MedicalInfo > Data

        {

            get

            {

                return this ._data;

            }

             set

            {

                this ._data = value ;

                OnPropertyChanged( "Data" );

            }

        }

 

        public LiveMonitor()

        {

            //start 5 second timer

            _timer = new System.Windows.Forms. Timer ();

            _timer.Interval = 5000;

            _timer.Tick += _timer_Tick;

            Data = _repo.RefreshMeasurements( DateTime .Now);

        }

 

        void _timer_Tick( object sender, EventArgs e)

        {

            Data = _repo.RefreshMeasurements( DateTime .Now);

        }

 

        public void StartMonitor()

        {

            _timer.Start();

        }

 

        public void StopMonitor()

        {

            _timer.Stop();

        }

 

        public event PropertyChangedEventHandler PropertyChanged;

 

        protected virtual void OnPropertyChanged( string propertyName)

        {

            if (PropertyChanged != null )

            {

                PropertyChanged( this , new PropertyChangedEventArgs (propertyName));

            }

        }

    }

 

    public class MedicalInfoRepository

    {

        private BindingList < MedicalInfo > _data = new BindingList < MedicalInfo >();

 

        public BindingList < MedicalInfo > RefreshMeasurements( DateTime start)

        {

            //Generate Random Medical Data

            _data.Clear();

            for ( int i = 0; i <5; i++)

            {

                Thread .Sleep(5);

                Random r = new Random ( DateTime .Now.Millisecond);

                MedicalInfo toAdd = new MedicalInfo ();

                toAdd.TimeOfMeasurement = start;

                start = start.AddSeconds(1);

                toAdd.HeartRate = r.Next(60, 100);

                toAdd.SystolicBloodPressure = r.Next(110, 130);

                toAdd.DiastolicBloodPressure = r.Next(70, 85);

                _data.Add(toAdd);

            }

 

            return _data;

        }

    }

}

Figure 2 – MedicalInfo class, LiveMonitor and MedicalInfoRepository class listings

Next we will need to implement the user interface, ensure that you drag an instance of the RadChartView control onto the design surface of your form. In the code-behind of the form, also declare a private instance of the LiveMonitor class as follows:

private LiveMonitor _monitor = new LiveMonitor ();

Figure 3– Instantiating a LiveMonitor field in the Form code-behind

Now we will initialize the RadChartView, using the multi-axes feature of the control so that heart rate can be visualized with blood pressure all in the same chart. To do this, create a method in your form code-behind as follows:

public void InitializeChart()

{

    DateTimeContinuousAxis timeAxis = new DateTimeContinuousAxis ();

    timeAxis.MajorStepUnit = Telerik.Charting. TimeInterval .Second;

    timeAxis.MajorStep = 1;

    timeAxis.LabelFormat = "{0:hh:mm:ss}" ;

    timeAxis.LabelRotationAngle = 310;

    timeAxis.Title = "Time of Measurement" ;

 

    LinearAxis hr = new LinearAxis ();

    hr.MajorStep = 10;

    hr.AxisType = Telerik.Charting. AxisType .Second;

    hr.Title = "Heart Rate (beats per minute)" ;

 

    LinearAxis bp = new LinearAxis ();

    bp.MajorStep = 25;

    bp.AxisType = Telerik.Charting. AxisType .Second;

    bp.HorizontalLocation = Telerik.Charting. AxisHorizontalLocation .Right;

    bp.Title = "Blood Pressure (mm Hg)" ;

 

    //first series, heart rate

    LineSeries heartRate = new LineSeries ();

    heartRate.LegendTitle = "Heart Rate" ;

    heartRate.ValueMember = "HeartRate" ;

    heartRate.CategoryMember = "TimeOfMeasurement" ;

    heartRate.VerticalAxis = hr;

    heartRate.HorizontalAxis = timeAxis;

    heartRate.DataSource = _monitor.Data;

 

    BarSeries systolic = new BarSeries ();

    systolic.LegendTitle = "Systolic Blood Pressure" ;

    systolic.ValueMember = "SystolicBloodPressure" ;

    systolic.CategoryMember = "TimeOfMeasurement" ;

    systolic.VerticalAxis = bp;

    systolic.HorizontalAxis = timeAxis;

    systolic.DataSource = _monitor.Data;

 

    BarSeries diastolic = new BarSeries ();

    diastolic.LegendTitle = "Diastolic BloodPressure" ;

    diastolic.ValueMember = "DiastolicBloodPressure" ;

    diastolic.CategoryMember = "TimeOfMeasurement" ;

    diastolic.VerticalAxis = bp;

    diastolic.HorizontalAxis = timeAxis;

    diastolic.DataSource = _monitor.Data;

 

    this .radChartView1.ShowLegend = true ;

    this .radChartView1.Series.Add(heartRate);

     this .radChartView1.Series.Add(systolic);

    this .radChartView1.Series.Add(diastolic);

    this .radChartView1.Area.View.Palette = KnownPalette .Metro;

}

Figure 4 – Instantiating RadChartView for medical monitoring

The InitializeChart method defines each axis displayed in the chart, the x axis, the time axis, being the common axis. The left-hand y axis will measure the heart rate of the patient, and the right-hand y-axis is responsible for measuring the systolic and diastolic blood pressure of the patient. This method is also responsible for defining the series’ being displayed in the chart. The first series is a line graph for the heart rate, and the two bar series are responsible for displaying blood pressure data. Be sure to call the InitializeChart method in the Form constructor:

InitializeChart();

Figure 5 – Calling the InitializeChart method from within the Form constructor

The last thing we need to do to implement this example is to start and stop the Live Monitor. To do this implement the Load and Leave event handlers as follows:

private void Form1_Load( object sender, EventArgs e)

{

    _monitor.StartMonitor();

}

 

private void Form1_Leave( object sender, EventArgs e)

{

    _monitor.StopMonitor();

}

Figure 6 – Starting and Stopping the Live Monitor in the Form Load and Leave event handlers

When the application is run the chart will update every 5 seconds. Please note that this is strictly generated medical data, I’m sure that if this were a real person that they would have some significant health concerns!

CONCLUSION

From this scenario, you can see that real-time data feeds are much better served with a control suite solution. In the next blog post we will review a scenario where a Reporting solution should be used.

 

DOWNLOAD SOURCE

 

Download RadControls for WinForms by Telerik

Download Telerik Reporting


About the Author

Carey Payette

is a Developer Advocate. You can follow Carey on Twitter @careypayette or read her personal blog at www.codingbandit.com.

Related Posts

Comments

Comments are disabled in preview mode.