This question is locked. New answers and comments are not allowed.
Hi,
In our project we are using the Telerik RedCartitionChart(Line Series) control to display the live ECG data, we are showing 14 different instances of live ECG Chart / red chart on the single page.
The app is connected to a hardware device which is transmitting the live ECG data which we are then reading and plotting it on the graph. Working mechanism of plotting the data is, by assigning a starting point, "0" and mapping the live data on it as it comes in. The loop will go from point "0" to "[Length(N)]", where N is a predetermined amount (3000). Once the loop reaches "N", then we restart it from point "0" and we start the mapping process again and at the same time removing the previously mapped data.
The issue faced by us is that after 10-15 min of continuous plotting the points on the graph the performance of the application reduced drastically. The graphs become slow and the application UI is unresponsive.
Please find attached screen shot for the same.
Thanks in advance. Looking forward for your response.
Thanks
Harsh.
In our project we are using the Telerik RedCartitionChart(Line Series) control to display the live ECG data, we are showing 14 different instances of live ECG Chart / red chart on the single page.
The app is connected to a hardware device which is transmitting the live ECG data which we are then reading and plotting it on the graph. Working mechanism of plotting the data is, by assigning a starting point, "0" and mapping the live data on it as it comes in. The loop will go from point "0" to "[Length(N)]", where N is a predetermined amount (3000). Once the loop reaches "N", then we restart it from point "0" and we start the mapping process again and at the same time removing the previously mapped data.
The issue faced by us is that after 10-15 min of continuous plotting the points on the graph the performance of the application reduced drastically. The graphs become slow and the application UI is unresponsive.
Please find attached screen shot for the same.
Thanks in advance. Looking forward for your response.
Thanks
Harsh.
5 Answers, 1 is accepted
0
Hi Harsh,
Thank you for contacting us! From the description it seems that there might be some kind of memory usage issue. However, we have not encountered similar behavior, so far.
Would it be possible to elaborate a little more on the setup of the charts, how the data is added removed, how it is bound to the component. If possible can you send us code snippets or stripped down project where the issue is present in order to suggest the most effective course of action and setup for this scenario.
Regards,
Tsvyatko
Telerik
Thank you for contacting us! From the description it seems that there might be some kind of memory usage issue. However, we have not encountered similar behavior, so far.
Would it be possible to elaborate a little more on the setup of the charts, how the data is added removed, how it is bound to the component. If possible can you send us code snippets or stripped down project where the issue is present in order to suggest the most effective course of action and setup for this scenario.
Regards,
Tsvyatko
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.
0

Harsh
Top achievements
Rank 1
answered on 12 Feb 2015, 10:43 AM
Hello Tsvyatko,
Thanks for the response on the issue.
The step-by step scenario of the code is something like this.
1) we have one button click (PlayButton) on which we are starting one timer "PlotDataTimer_Tick".
2) when "PlotDataTimer_Tick" is started at that time we invoking on function called "PlotLeadData()", we have invoking this function in the Dispatcher as because we are side-by side reading the data from the dongle(Device which is transmitting the data via BT to the application)
private async void PlotDataTimer_Tick(object sender, object e)
{
try
{
CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Low,
new DispatchedHandler(async () =>
{
Ecg12LeadChartingData.PlotLeadData();
}));
}
}
3) The PlotLeadData() function is used for the calculation/encoding the data from the device in such formate which is known to graph(in this case double value) and after receiving proper values for the each graph we are plotting same on the graph one after the other.
internal void PlotLeadData()
{
if (BluetoothHelper.Instance.WaveDataList.Count > 10 &&
initLeadCount >= MinDataLength)
{
LeadDataList.SuspendNotifications();
var waveItes =
BluetoothHelper.Instance.WaveDataList.GetRange(0, 10);
Ploat10Points(LeadDataList, waveItes, ref LeadCount);
BluetoothHelper.Instance.WaveDataList.RemoveRange(0, 10);
LeadDataList.ResumeNotifications();
}
}
4) In the above function PlotLeadData() we used one method called ploat10points() which is gradually plot the vales on the graph(replacing the object from the starting index).
For this method we have defined the pre define points for the ease of us like
private int LeadCount = 1400;
private static int DataLength = 1400;
We are using MVVM architecture. We have bind a ObservableCollection (RangeObservableCollection) type to all the graphs.
On load we are adding by default 1400 records to the list. At the time of plotting we are replacing the object from starting index 0 to 1400 an so on.
private static void
Ploat10Points(RangeObservableCollection<ENTLeadValue> leadList,
List<ENTLeadValue> waveItes, ref int leadCount)
{
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount] = waveItes[0];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[1];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[2];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[3];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[4];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[5];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[6];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[7];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[8];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[9];
}
public static void
RemoveLeadValue(RangeObservableCollection<ENTLeadValue> list, int count)
{
if (count + 1 < DataLength) list[count + 1] = null;
if (count + 2 < DataLength) list[count + 2] = null;
if (count + 3 < DataLength) list[count + 3] = null;
if (count + 4 < DataLength) list[count + 4] = null;
if (count + 5 < DataLength) list[count + 5] = null;
if (count + 6 < DataLength) list[count + 6] = null;
if (count + 7 < DataLength) list[count + 7] = null;
if (count + 8 < DataLength) list[count + 8] = null;
if (count + 9 < DataLength) list[count + 9] = null;
if (count + 10 < DataLength) list[count + 10] = null;
}
--
Thanks,
Harsh
Thanks for the response on the issue.
The step-by step scenario of the code is something like this.
1) we have one button click (PlayButton) on which we are starting one timer "PlotDataTimer_Tick".
2) when "PlotDataTimer_Tick" is started at that time we invoking on function called "PlotLeadData()", we have invoking this function in the Dispatcher as because we are side-by side reading the data from the dongle(Device which is transmitting the data via BT to the application)
private async void PlotDataTimer_Tick(object sender, object e)
{
try
{
CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Low,
new DispatchedHandler(async () =>
{
Ecg12LeadChartingData.PlotLeadData();
}));
}
}
3) The PlotLeadData() function is used for the calculation/encoding the data from the device in such formate which is known to graph(in this case double value) and after receiving proper values for the each graph we are plotting same on the graph one after the other.
internal void PlotLeadData()
{
if (BluetoothHelper.Instance.WaveDataList.Count > 10 &&
initLeadCount >= MinDataLength)
{
LeadDataList.SuspendNotifications();
var waveItes =
BluetoothHelper.Instance.WaveDataList.GetRange(0, 10);
Ploat10Points(LeadDataList, waveItes, ref LeadCount);
BluetoothHelper.Instance.WaveDataList.RemoveRange(0, 10);
LeadDataList.ResumeNotifications();
}
}
4) In the above function PlotLeadData() we used one method called ploat10points() which is gradually plot the vales on the graph(replacing the object from the starting index).
For this method we have defined the pre define points for the ease of us like
private int LeadCount = 1400;
private static int DataLength = 1400;
We are using MVVM architecture. We have bind a ObservableCollection (RangeObservableCollection) type to all the graphs.
On load we are adding by default 1400 records to the list. At the time of plotting we are replacing the object from starting index 0 to 1400 an so on.
private static void
Ploat10Points(RangeObservableCollection<ENTLeadValue> leadList,
List<ENTLeadValue> waveItes, ref int leadCount)
{
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount] = waveItes[0];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[1];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[2];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[3];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[4];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[5];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[6];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[7];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[8];
if (leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[9];
}
public static void
RemoveLeadValue(RangeObservableCollection<ENTLeadValue> list, int count)
{
if (count + 1 < DataLength) list[count + 1] = null;
if (count + 2 < DataLength) list[count + 2] = null;
if (count + 3 < DataLength) list[count + 3] = null;
if (count + 4 < DataLength) list[count + 4] = null;
if (count + 5 < DataLength) list[count + 5] = null;
if (count + 6 < DataLength) list[count + 6] = null;
if (count + 7 < DataLength) list[count + 7] = null;
if (count + 8 < DataLength) list[count + 8] = null;
if (count + 9 < DataLength) list[count + 9] = null;
if (count + 10 < DataLength) list[count + 10] = null;
}
--
Thanks,
Harsh
0

Harsh
Top achievements
Rank 1
answered on 12 Feb 2015, 10:47 AM
Hello Tsvyatko,
Thanks for the response on the issue.
The step-by step scenario of the code is something like this.
1) we have one button click (PlayButton) on which we are starting one timer "PlotDataTimer_Tick".
2) when "PlotDataTimer_Tick" is started at that time we invoking on function called "PlotLeadData()", we have invoking this function in the Dispatcher as because we are side-by side reading the data from the dongle(Device which is transmitting the data via BT to the application)
3) The PlotLeadData() function is used for the calculation/encoding the data from the device in such formate which is known to graph(in this case double value) and after receiving proper values for the each graph we are plotting same on the graph one after the other.
4) In the above function PlotLeadData() we used one method called ploat10points() which is gradually plot the vales on the graph(replacing the object from the starting index).
For this method we have defined the pre define points for the ease of us like
We are using MVVM architecture. We have bind a ObservableCollection (RangeObservableCollection) type to all the graphs.
On load we are adding by default 1400 records to the list. At the time of plotting we are replacing the object from starting index 0 to 1400 an so on.
--
Thanks,
Harsh Jain
Thanks for the response on the issue.
The step-by step scenario of the code is something like this.
1) we have one button click (PlayButton) on which we are starting one timer "PlotDataTimer_Tick".
2) when "PlotDataTimer_Tick" is started at that time we invoking on function called "PlotLeadData()", we have invoking this function in the Dispatcher as because we are side-by side reading the data from the dongle(Device which is transmitting the data via BT to the application)
private
async
void
PlotDataTimer_Tick(
object
sender,
object
e)
{
try
{
CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Low,
new
DispatchedHandler(async () =>
{
Ecg12LeadChartingData.PlotLeadData();
}));
}
}
3) The PlotLeadData() function is used for the calculation/encoding the data from the device in such formate which is known to graph(in this case double value) and after receiving proper values for the each graph we are plotting same on the graph one after the other.
internal
void
PlotLeadData()
{
if
(BluetoothHelper.Instance.WaveDataList.Count > 10 &&
initLeadCount >= MinDataLength)
{
LeadDataList.SuspendNotifications();
var waveItes =
BluetoothHelper.Instance.WaveDataList.GetRange(0, 10);
Ploat10Points(LeadDataList, waveItes,
ref
LeadCount);
BluetoothHelper.Instance.WaveDataList.RemoveRange(0, 10);
LeadDataList.ResumeNotifications();
}
}
4) In the above function PlotLeadData() we used one method called ploat10points() which is gradually plot the vales on the graph(replacing the object from the starting index).
For this method we have defined the pre define points for the ease of us like
private
int
LeadCount = 1400;
private
static
int
DataLength = 1400;
We are using MVVM architecture. We have bind a ObservableCollection (RangeObservableCollection) type to all the graphs.
On load we are adding by default 1400 records to the list. At the time of plotting we are replacing the object from starting index 0 to 1400 an so on.
private
static
void
Ploat10Points(RangeObservableCollection<ENTLeadValue> leadList,
List<ENTLeadValue> waveItes,
ref
int
leadCount)
{
if
(leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount] = waveItes[0];
if
(leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[1];
if
(leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[2];
if
(leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[3];
if
(leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[4];
if
(leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[5];
if
(leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[6];
if
(leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[7];
if
(leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[8];
if
(leadCount >= DataLength) leadCount = 0;
RemoveLeadValue(leadList, leadCount); leadList[leadCount++] = waveItes[9];
}
public
static
void
RemoveLeadValue(RangeObservableCollection<ENTLeadValue> list,
int
count)
{
if
(count + 1 < DataLength) list[count + 1] =
null
;
if
(count + 2 < DataLength) list[count + 2] =
null
;
if
(count + 3 < DataLength) list[count + 3] =
null
;
if
(count + 4 < DataLength) list[count + 4] =
null
;
if
(count + 5 < DataLength) list[count + 5] =
null
;
if
(count + 6 < DataLength) list[count + 6] =
null
;
if
(count + 7 < DataLength) list[count + 7] =
null
;
if
(count + 8 < DataLength) list[count + 8] =
null
;
if
(count + 9 < DataLength) list[count + 9] =
null
;
if
(count + 10 < DataLength) list[count + 10] =
null
;
}
--
Thanks,
Harsh Jain
0
Hello Harsh,
Thank you for sharing this information with us! We will investigate this further to determine the cause of the performance degradation. We will write you back shortly.
Regards,
Tsvyatko
Telerik
Thank you for sharing this information with us! We will investigate this further to determine the cause of the performance degradation. We will write you back shortly.
Regards,
Tsvyatko
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.
0
Hi Harsh,
We have tested this scenario on different devices and we did not found indication of performance degradation over time. There is slight delay that can be observed due to the heavy load of the UI, amount of data and refresh interval, however, the frame rate and the memory consumption does not change after continuous use.
What I can suggest is to check whether the issue is reproducible when the Chart is supplied with dummy data and not collected from external source. If this is the case would it be possible to send us stripped down version of the project or modify the one attached where the issue is reproducible.
Regards,
Tsvyatko
Telerik
We have tested this scenario on different devices and we did not found indication of performance degradation over time. There is slight delay that can be observed due to the heavy load of the UI, amount of data and refresh interval, however, the frame rate and the memory consumption does not change after continuous use.
What I can suggest is to check whether the issue is reproducible when the Chart is supplied with dummy data and not collected from external source. If this is the case would it be possible to send us stripped down version of the project or modify the one attached where the issue is reproducible.
Regards,
Tsvyatko
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.