Good morning everyone, I have a working TKChart series , however I want to include a timeline on the xAxis , I have been trying to follow the code from Telerik without any luck. Does anyone have any working code to include this timeline ? What I am looking for is a timeline for just an 8 hour period.
Any help is greatly appreciated.
Regards
JZ
8 Answers, 1 is accepted
Hi John,
I have a series plotted against a TKChartDateTimeAxis on my xAxis. You can define this with max and min NSDate objects. Is that what you are looking for? How are you defining your series, maybe a snippet of your code would help?
Regards,
Allen
In order to include timeline on your xAxis you have to initialize your TKChartDataPoint objects with X properties of type NSDate. The code snippet below generates array of TKChartDataPoint objects which X properties are DataTime objects with same date but different hours.
NSCalendar
*calendar = [[
NSCalendar
alloc]
initWithCalendarIdentifier
:
NSCalendarIdentifierGregorian
];
NSDateComponents
*dateTimeComponents = [[
NSDateComponents
alloc]
init
];
dateTimeComponents
.year
=
2015
;
dateTimeComponents
.month
=
6
;
dateTimeComponents
.day
=
1
;
NSMutableArray
*randomData = [[
NSMutableArray
alloc]
init
];
for
(
int
i =
1
; i <=
8
; i++) {
dateTimeComponents
.hour
= i;
[randomData
addObject
:[[
TKChartDataPoint
alloc]
initWithX
:[calendar
dateFromComponents
:dateTimeComponents]
Y
:
@
(
arc4random
() %
100
)]];
}
Then you should create TKChartDateTimeAxis with date range, set the majorTickIntervalUnit property to TKChartDateTimeAxisIntervalUnitHours and adjust the majorTickInterval property.
TKChartDateTimeAxis
*xAxis = [[
TKChartDateTimeAxis
alloc]
initWithMinimumDate
:minDate
andMaximumDate
:maxDate];
xAxis
.majorTickIntervalUnit
= TKChartDateTimeAxisIntervalUnitHours;
xAxis
.majorTickInterval
=
1
;
_chart
.xAxis
= xAxis;
If you have any other questions do not hesitate to contact us.
Regards,
Sophi
Telerik
Hello Sophi, thanks so much for showing the sample code to me, however being that I am quite new to Telerik, it appears their are two items missing minDate and maxDate , showing up as errors on my code.
I want to accomplish I have recorded data from a 6 - 8 hour period so i would like to display a time line reflecting that. And where in the Telerik code does the sample you supplied me go. for i.e.
Question 1 where do I create minDate and maxDate ?
HERE ?-
- (TKChartSeries *)seriesForChart:(TKChart *)chart atIndex:(NSUInteger)index
{
TKChartLineSeries *series = [chart dequeueReusableSeriesWithIdentifier:@"series1"];
if (!series) { //_tkCountArray
series = [[TKChartLineSeries alloc] initWithItems:_tkCountArray reuseIdentifier:@"series1"];
series.title = @"Delegate series";
}
return series;
}
OR HERE -
- (id<TKChartData>)chart:(TKChart *)chart dataPointAtIndex:(NSUInteger)dataIndex forSeriesAtIndex:(NSUInteger)seriesIndex
{
//dataIndex
TKChartDataPoint *point = [[TKChartDataPoint alloc] initWithX:@(dataIndex)Y:@(arc4random() % 100)];
return point;
}
Regards
JZ
Your minDate is the first date in the interval you are displaying, for example if you want to display the hours between 1 and 6 on 7th May 2015 your minDate is 5th May 2015 01:00:00 and your maxDate is 5th May 06:00:00
You can initialize TKChart in the viewDidLoad method. Here is code snippet for that.
- (
void
)viewDidLoad {
TKChart
*_chart = [[
TKChart
alloc]
initWithFrame
:
self
.view
.bounds
];
_chart
.autoresizingMask
=
UIViewAutoresizingFlexibleWidth
|
UIViewAutoresizingFlexibleHeight
;
[
self
.view
addSubview
:_chart];
NSCalendar
*calendar = [[
NSCalendar
alloc]
initWithCalendarIdentifier
:
NSCalendarIdentifierGregorian
];
NSDateComponents
*dateTimeComponents = [[
NSDateComponents
alloc]
init
];
dateTimeComponents
.year
=
2015
;
dateTimeComponents
.month
=
5
;
dateTimeComponents
.day
=
7
;
NSMutableArray
*array = [[
NSMutableArray
alloc]
init
];
for
(
int
i =
1
; i <=
6
; i++) {
dateTimeComponents
.hour
= i;
[array
addObject
:[[
TKChartDataPoint
alloc]
initWithX
:[calendar
dateFromComponents
:dateTimeComponents]
Y
:
@
(
arc4random
() %
100
)]];
}
TKChartSplineAreaSeries
*series = [[
TKChartSplineAreaSeries
alloc]
initWithItems
:array];
series
.selectionMode
= TKChartSeriesSelectionModeSeries;
dateTimeComponents
.hour
=
1
;
NSDate
*minDate = [calendar
dateFromComponents
:dateTimeComponents];
dateTimeComponents
.hour
=
6
;
NSDate
*maxDate = [calendar
dateFromComponents
:dateTimeComponents];
TKChartDateTimeAxis
*xAxis = [[
TKChartDateTimeAxis
alloc]
initWithMinimumDate
:minDate
andMaximumDate
:maxDate];
xAxis
.majorTickIntervalUnit
= TKChartDateTimeAxisIntervalUnitHours;
xAxis
.majorTickInterval
=
1
;
_chart
.xAxis
= xAxis;
[_chart
addSeries
:series];
}
Regards
Yoanna
Telerik
Good morning Yoanna, thank you much for getting back to me so fast, I am listing my methods that produce a working Telerik chart based on my data. My data comes from tapping a tableView cell and populates the Chart with no issues, however when I try to implement the Series for Date Line I get errors, Below is the code that works, maybe you can show me how to incorporate what you sent as Demo code into my project. I cannot get it to work.
The (void) method below is called when a user taps a tableView Cell , and like i mentioned it produces a chart, however when I try to implement the Series like you showed me it does not work.
-(void) showChartData {
if (sleepDataVC.date > 0) {
TKChart *chartTop = [[TKChart alloc]initWithFrame:CGRectMake(_scrollView.bounds.origin.x,_scrollView.bounds.origin.y, _scrollView.bounds.size.width, _scrollView.bounds.size.height)];
chartTop.dataSource = self;
chartTop.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.scrollView addSubview:chartTop];
/*
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *dateTimeComponents = [[NSDateComponents alloc] init];
dateTimeComponents.year = 2015;
dateTimeComponents.month = 5;
dateTimeComponents.day = 7;
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int i = 1; i <= 6; i++) {
dateTimeComponents.hour = i;
[array addObject:[[TKChartDataPoint alloc] initWithX:[calendar dateFromComponents:dateTimeComponents] Y:@(arc4random() % 100)]];
}
TKChartSplineAreaSeries *series = [[TKChartSplineAreaSeries alloc] initWithItems:array];
series.selectionMode = TKChartSeriesSelectionModeSeries;
dateTimeComponents.hour= 1;
NSDate *minDate = [calendar dateFromComponents:dateTimeComponents];
dateTimeComponents.hour = 6;
NSDate *maxDate = [calendar dateFromComponents:dateTimeComponents];
TKChartDateTimeAxis *xAxis = [[TKChartDateTimeAxis alloc] initWithMinimumDate:minDate andMaximumDate:maxDate];
xAxis.majorTickIntervalUnit = TKChartDateTimeAxisIntervalUnitHours;
xAxis.majorTickInterval = 1;
chartTop.xAxis = xAxis;
[chartTop addSeries:series];
*/
} else {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Baby G" message:@"There is No Sleep Data" delegate:self cancelButtonTitle:@"Okay" otherButtonTitles:@"Record Sleep Data and try again", nil];
[alert show];
}
}
- (NSUInteger)numberOfSeriesForChart:(TKChart *)chart
{
return 1;
}
- (TKChartSeries *)seriesForChart:(TKChart *)chart atIndex:(NSUInteger)index
{
TKChartLineSeries *series = [chart dequeueReusableSeriesWithIdentifier:@"series1"];
if (!series) { //_tkCountArray
series = [[TKChartLineSeries alloc] initWithItems:_tkCountArray reuseIdentifier:@"series1"];
series.title = @"Delegate series";
}
return series;
}
- (NSUInteger)chart:(TKChart *)chart numberOfDataPointsForSeriesAtIndex:(NSUInteger)seriesIndex
{
return tkChartCount;
}
- (id<TKChartData>)chart:(TKChart *)chart dataPointAtIndex:(NSUInteger)dataIndex forSeriesAtIndex:(NSUInteger)seriesIndex
{
//dataIndex
TKChartDataPoint *point = [[TKChartDataPoint alloc] initWithX:@(dataIndex)Y:@(arc4random() % 100)];
return point;
}
Thank you so much.
JZ
I think I have located the issue. There are two approaches to initialize TKChart. The first one is by adopting TKChartDataSource protocol like you did. The second option is by adding series directly to the chart. You can choose between those two options, however you can't mix them.
You can use the showChartData method to create your chart and setup the xAxis to show hours by setting minDate and maxDate properties which depend on your data. I assume that your minDate is the X value of the first object in your data array and maxDate is the X value of the last object.
In seriesForChart:atIndex: method you should provide the series your chart is going to use, in your case TKChartLineSeries and populate them.
In chart:dataPointAtIndex:forSeriesAtIndex: you should provide an instance ofTKChartDataPoint for the current index. So you should return the object at dataIndex position in your data array(which populates the chart).
And in chart:numberOfDataPointsForSeriesAtIndex: you should return the number of TKChartDataPoint objects your chart is going to use, which is the number of objects in your populating data array;
Here is a modified version of your code that displays an x axis with hours:
-(
void
) showChartData {
if
(sleepDataVC
.date
>
0
) {
TKChart
*chartTop = [[
TKChart
alloc]initWithFrame:
CGRectMake
(_scrollView
.bounds
.origin
.x
,_scrollView
.bounds
.origin
.y
, _scrollView
.bounds
.size
.width
, _scrollView
.bounds
.size
.height
)];
chartTop
.dataSource
=
self
;
chartTop
.autoresizingMask
=
UIViewAutoresizingFlexibleWidth
|
UIViewAutoresizingFlexibleHeight
;
[
self
.scrollView
addSubview
:chartTop];
NSDate
*minDate = [[tkCountArray
objectAtIndex
:
0
]
dataXValue
];
NSDate
*maxDate = [[tkCountArray
objectAtIndex
:tkCountArray
.count
-
1
]
dataXValue
];
TKChartDateTimeAxis
*xAxis = [[
TKChartDateTimeAxis
alloc]
initWithMinimumDate
:minDate
andMaximumDate
:maxDate];
xAxis
.majorTickIntervalUnit
= TKChartDateTimeAxisIntervalUnitHours;
xAxis
.majorTickInterval
=
1
;
chartTop
.xAxis
= xAxis;
}
else
{
UIAlertView
*alert = [[
UIAlertView
alloc]initWithTitle:
@"Baby G"
message
:
@"There is No Sleep Data"
delegate
:
self
cancelButtonTitle
:
@"Okay"
otherButtonTitles
:
@"Record Sleep Data and try again"
,
nil
];
[alert
show
];
}
}
- (
NSUInteger
)numberOfSeriesForChart:(
TKChart
*)chart
{
return
1
;
}
- (
TKChartSeries
*)seriesForChart:(
TKChart
*)chart
atIndex
:(
NSUInteger
)index
{
TKChartLineSeries
*series = [chart
dequeueReusableSeriesWithIdentifier
:
@"series1"
];
if
(!series) {
//_tkCountArray
series = [[
TKChartLineSeries
alloc]
initWithItems
:tkCountArray
reuseIdentifier
:
@"series1"
];
series
.title
=
@"Delegate series"
;
}
return
series;
}
- (
NSUInteger
)chart:(
TKChart
*)chart
numberOfDataPointsForSeriesAtIndex
:(
NSUInteger
)seriesIndex
{
return
[tkCountArray
count
];
}
- (
id
<TKChartData>)chart:(
TKChart
*)chart
dataPointAtIndex
:(
NSUInteger
)dataIndex
forSeriesAtIndex
:(
NSUInteger
)seriesIndex
{
//dataIndex
TKChartDataPoint
*point = [tkCountArray
objectAtIndex
:dataIndex];
return
point;
}
I hope this helps.
Regards,
Sophi
Telerik
Hello, Yoanna ! Thanks so much for the help, but this does not work for me either, I am getting crashes either way I will explain to you what I am trying to accomplish and you could show me how to use your tools.
What I need is a working Chart which I have , but I just want to include the time line.
I am collecting data the following way.
1 – NSString current Date
2 – NSString beginTime
3 – NSString endTime
4 – NSString dataString
dataString collects the data for the chart , the other strings are self explanatory. I can convert these strings into a NSMutableArray or an NSArray or a NSData format to use with the charts. From my original code I sent to you I have a working TKChart, and the Produced chart shows my data points on the xAxis each one of those points represents an important event, I just want to add a time line to those events, but you explained that I was trying to use two different methods combined and the solution you so generously supplied did not work. If you may supply a way for me to use my data to create a solution I need. My company is definitely going to purchase the 3 package solution for iOS , Windows, Android.
Thanks again
JZ
Thank you for writing us back.
I am not sure that I fully understand your scenario. Could you, please prepare a sample application which demonstrates the case and send it to us. This will allow us to understand the exact scenario and provide you with a proper solution. Please, could you describe also what you mean by timeline. Maybe you can send us a picture of the desired outlook?
Looking forward to your reply.
Regards,
Sophi
Telerik