如何使用 objective c 绘制基于 json 数据的 Shinobi 图而不使用键
how to plot a Shinobi graph based on json data without key using objective c
我在下面这个结构中绘制 json 数据时遇到问题。
{"response":{"hash":"0fea72f2bea9820c18227a655b42fe66","resp_code":"GRAPH_RETRIEVED","code":200},"resultstats":{"record_count":46},"ana_uoms":["°C"],"data":[{"asset_id":204,"company_id":30,"asset_name":"WIF","stats":{"min":1.4,"max":6.9,"min_tstamps_count":1,"min_tstamps":["2015-03-17 08:30:00"],"max_tstamps":["2015-03-17 11:00:00","2015-03-17 11:30:00","2015-03-17 13:40:00","2015-03-17 14:50:00"],"mkt":5.91,"max_tstamps_count":4,"avg":5.8},"component_type":"ana_in","component_description":"WFt","site_name":"Kll","alarms":[],"sampling_rate":10,"region_name":"ll","component_id":8340,"company_name":"lb","uom":"°C","uom_decimal_places":1,"unit_sn":"3310","resolves":[],"records":[["2015-03-17 08:00",2.6],["2015-03-17 08:10",3.9],["2015-03-17 08:20",2.4],["2015-03-17 08:30",1.4],["2015-03-17 08:40",3.1],["2015-03-17 08:50",4.4],["2015-03-17 09:00",5.1],["2015-03-17 09:10",5.5],["2015-03-17 09:20",6.1],["2015-03-17 09:30",6.2],["2015-03-17 09:40",5.3],["2015-03-17 09:50",6.4],["2015-03-17 10:00",6.6],["2015-03-17 10:10",6.7],["2015-03-17 10:20",6.8],["2015-03-17 10:30",5.2],["2015-03-17 10:40",6.3],["2015-03-17 10:50",6.7],["2015-03-17 11:00",6.9],["2015-03-17 11:10",6],["2015-03-17 11:20",6.6],["2015-03-17 11:30",6.9],["2015-03-17 11:40",5.9],["2015-03-17 11:50",6.6],["2015-03-17 12:00",6.8],["2015-03-17 12:10",6.1],["2015-03-17 12:20",6.6],["2015-03-17 12:30",5.6],["2015-03-17 12:40",6.2],["2015-03-17 12:50",6.8],["2015-03-17 13:00",5.7],["2015-03-17 13:10",6.6],["2015-03-17 13:20",5.8],["2015-03-17 13:30",6.4],["2015-03-17 13:40",6.9],["2015-03-17 13:50",6],["2015-03-17 14:00",6.7],["2015-03-17 14:10",5.2],["2015-03-17 14:20",6.5],["2015-03-17 14:30",5.8],["2015-03-17 14:40",6.3],["2015-03-17 14:50",6.9],["2015-03-17 15:00",6.6],["2015-03-17 15:10",5.9],["2015-03-17 15:20",6.3],["2015-03-17 15:30",6.5]]},{"asset_id":204,"company_id":30,"asset_name":"Wft","stats":{"min":2.9,"max":6.8,"min_tstamps_count":1,"min_tstamps":["2015-03-17 08:30:00"],"max_tstamps":["2015-03-17 11:00:00","2015-03-17 11:30:00","2015-03-17 12:00:00","2015-03-17 13:40:00"],"mkt":5.8,"max_tstamps_count":4,"avg":5.7},"component_type":"ana_in","component_description":"WIF Right Back","site_name":"Ktore","alarms":[],"sampling_rate":10,"region_name":"Kano","component_id":8341,"company_name":"lls","uom":"°C","uom_decimal_places":1,"unit_sn":"3310","resolves":[],"records":[["2015-03-17 08:00",3.2],["2015-03-17 08:10",4.2],["2015-03-17 08:20",3.1],["2015-03-17 08:30",2.9],["2015-03-17 08:40",3.7],["2015-03-17 08:50",4.5],["2015-03-17 09:00",5.2],["2015-03-17 09:10",5.6],["2015-03-17 09:20",6.1],["2015-03-17 09:30",6.3],["2015-03-17 09:40",4.8],["2015-03-17 09:50",6.3],["2015-03-17 10:00",6.5],["2015-03-17 10:10",6.6],["2015-03-17 10:20",6.7],["2015-03-17 10:30",4.5],["2015-03-17 10:40",6.3],["2015-03-17 10:50",6.6],["2015-03-17 11:00",6.8],["2015-03-17 11:10",5.9],["2015-03-17 11:20",6.5],["2015-03-17 11:30",6.8],["2015-03-17 11:40",5.7],["2015-03-17 11:50",6.5],["2015-03-17 12:00",6.8],["2015-03-17 12:10",5.9],["2015-03-17 12:20",6.6],["2015-03-17 12:30",5],["2015-03-17 12:40",6.2],["2015-03-17 12:50",6.7],["2015-03-17 13:00",5.5],["2015-03-17 13:10",6.5],["2015-03-17 13:20",5.2],["2015-03-17 13:30",6.2],["2015-03-17 13:40",6.8],["2015-03-17 13:50",5.8],["2015-03-17 14:00",6.6],["2015-03-17 14:10",4.5],["2015-03-17 14:20",6.4],["2015-03-17 14:30",5.2],["2015-03-17 14:40",6.2],["2015-03-17 14:50",6.7],["2015-03-17 15:00",6.4],["2015-03-17 15:10",5.2],["2015-03-17 15:20",6.2],["2015-03-17 15:30",6.1]]}],"ana_thresholds":[["<1.0"],[">8.0"]],"parameters":{"end_date":"2015-03-17 15:30","start_date":"2015-03-17 08:00","sampling_rate":10}}
我基本上是在尝试使用 Shinobi 图形库试用版来绘制此 json 数据,但我完全不知道如何解析上面的对象。在 json 中,我有日期时间和温度值。我设法在我的控制台中看到解析响应。但是该图没有要绘制的对象数据,因为我没有将任何 json 值传递给该系列,因为我不知道它是如何完成的。请提供帮助,因为我在 Whosebug 中没有看到类似的问题。
这是我的代码片段。
- (void) loadData{
// Parse units offline from the webservice.
@try{
NSString *delete = [[NSString alloc] initWithFormat:@""];
NSString *logOut = [NSString stringWithFormat:@"MY URL"];
NSURL *url=[NSURL URLWithString:logOut];
NSLog(@"Asset list: %@", url);
NSData *postData =[delete dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [ NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:@"GET"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setHTTPBody:postData];
//[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(@"Reponse code: %ld", (long)[response statusCode]);
if ([response statusCode] >= 200 && [response statusCode] < 300)
{
NSLog(@"Response ==> %@", responseData);
@try{
NSError *error = nil;
// NSMutableArray* jsonDetails = [[NSMutableArray alloc]init];
NSDictionary *jsonDetails = [NSJSONSerialization JSONObjectWithData:urlData options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error];
NSArray *graphData = [ jsonDetails objectForKey:@"records"];
NSLog(@"Retrieving graph: %@", jsonDetails);
for (NSDictionary* jsonPoint in graphData) {
SChartDataPoint* datapoint = [self dataPointForDate:jsonPoint[@"date"]
andValue:jsonPoint[@"temp"]];
NSLog(@"SChart point: %@", datapoint);
[_timeSeries addObject:datapoint];
}
}
@catch (NSException *e){
NSLog(@"Try catch block: %@", e);
}
@finally{
// [self.tblRegion reloadData];
NSLog(@"finally");
}
}
}
@catch (NSException * e) {
NSLog(@"Exception: %@", e);
}
}
A shinobichart 使用与 UITableView
相同的模型来提供数据 - 因为它使用数据源对象。您需要一个符合 SChartDatasource
协议的对象 - 它有 4 个必需的方法来向图表提供数据。其中包括提供数据点的数量和数据点本身(以及其他)。
如果您将正在创建的数据点保存到一个数组中,那么您就可以使用适当的 SChartDatasource
方法将它们传递给图表。
这里不再重复,我将向您介绍 shinobicharts 快速入门指南,其中贯穿了向图表提供数据的基础知识:
shinobicontrols.com/docs/ShinobiControls/ShinobiCharts/2.7.0/Premium/Normal/user_guide.html
您在此处的 JSON 结构有一个具有以下结构的记录字段:
"records":[["2015-03-17 08:00",2.6],["2015-03-17 08:10",3.9],...
这是一个数组数组 - 即每个数据点都由一个数组表示 - 第一个元素是日期,第二个元素是值。
您需要更新以下内容:
for (NSDictionary* jsonPoint in graphData) {
SChartDataPoint* datapoint = [self dataPointForDate:jsonPoint[@"date"]
andValue:jsonPoint[@"temp"]];
NSLog(@"SChart point: %@", datapoint);
[_timeSeries addObject:datapoint];
}
而不是 NSDictionary
个对象,你实际上有 NSArray
:
for (NSArray* jsonPoint in graphData) {
SChartDataPoint* datapoint = [self dataPointForDate:jsonPoint[0]
andValue:jsonPoint[1]];
NSLog(@"SChart point: %@", datapoint);
[_timeSeries addObject:datapoint];
}
请注意,您 可能 必须将日期值从 NSString
解析为 NSDate
- 取决于您的 dataPointForDate:andValue:
方法做。您可以使用 NSDateFormatter
.
感谢 sammyd 的帮助,相信这是对我问题的一个接近的答案。下面的片段几乎是完美的。唯一的问题是我仍然需要更改日期格式以获取系列中的数据点。
{
NSLog(@"Response ==> %@", responseData);
NSError *error = nil;
jsonDetails = [NSJSONSerialization JSONObjectWithData:urlData options:kNilOptions error:&error];
NSArray *keys = [jsonDetails allKeys];
// values in foreach loop
for (NSString *key in keys) {
// NSLog(@"%@ is %@",key, [jsonDetails objectForKey:key]);
data = [jsonDetails objectForKey:@"data"];
graphData = [data[0]objectForKey:@"records"];
datapoint = [[SChartDataPoint alloc] init];
// NSLog(@"Record for the graph: %@", graphData);
// results = [jsonDetails objectForKey:@"resultstats"];
// recordCount = [results objectForKey:@"record_count"];
for (int i=0; i< [graphData count]; i++){
NSArray *record = graphData[i];
// NSLog(@"Record value: %@", record);
datapoint.xValue = record[0]; // date
NSLog(@"Date/time: %@", datapoint.xValue);
datapoint.yValue = record[1]; // number
NSLog(@"Temp: %@", datapoint.yValue);
datapoint = [self dataPointForDate:datapoint.xValue
andValue:datapoint.yValue];
NSLog(@"Adding datapoint to series: %@", datapoint);
[_timeSeries addObject:datapoint];
}
}
}
这是控制台输出。我不会粘贴整个控制台输出,因为 json 响应和我用于调试 purpose.You 的 NSLog 在我将数据点对象添加到系列时出于某种原因可以看到。 datapoint.xValue 为空,因此我仍然没有在应用程序中看到图表。我已将日期格式更改为 yyyy-MM-dd HH:mm,这是我的控制台输出。仍然没有绘制图表。
TimeSeriesChart[952:468171] Adding datapoint to series: { index=0, x=2015-03-22 13:20:00 +0000, y=6.4, selected=N }
2015-03-23 07:49:01.682 TimeSeriesChart[952:468171] Date/time: 2015-03-22 15:30
2015-03-23 07:49:01.683 TimeSeriesChart[952:468171] Temp: 6.3
2015-03-23 07:49:01.685 TimeSeriesChart[952:468171] Time/Date format: 2015-03-22 13:30:00 +0000
2015-03-23 07:49:01.685 TimeSeriesChart[952:468171] Adding datapoint to series: { index=0, x=2015-03-22 13:30:00 +0000, y=6.3, selected=N }
2015-03-23 07:49:01.697 TimeSeriesChart[952:468171] ShinobiCharts: Attempting to update axis data range with nil series min or max. Axis range not updated.
From: SChartDateTimeAxis at 0x15d64d10, axisRange = { 0.000000, 1.000000 }, defaultRange = { 1970-01-01 00:00:00 +0000, 1970-01-01 00:00:01 +0000 }, maxRange = { 1970-01-01 00:00:00 +0000, 1970-01-01 00:00:01 +0000 }
2015-03-23 07:49:01.698 TimeSeriesChart[952:468171] ShinobiCharts: Attempting to update axis data range with nil series min or max. Axis range not updated.
From: SChartNumberAxis at 0x19c852e0, axisRange = { 0.000000, 1.000000 }, defaultRange = { 0.000000, 1.000000 }, maxRange = { 0.000000, 1.000000 }
我按照 sammyd 的建议回答修复了上述错误;
for (NSArray *record in graphData) {
// NSArray *record = graphData[i];
// NSLog(@"Record value: %@", record);
NSString *dateString = [NSString stringWithFormat:@"%@",[record objectAtIndex:0]];
NSDate *date = [self dateFromString:dateString];
datapoint.xValue = date; // date
NSLog(@"Date/time: %@", datapoint.xValue);
// NSString *date = datapoint.xValue;
datapoint.yValue = record[1]; // number
NSLog(@"Temp: %@", datapoint.yValue);
datapoint = [self dataPointForDate:record[0]
andValue:record[1]];
NSLog(@"Adding datapoint to series: %@", datapoint);
[_timeSeries addObject:datapoint];
}
我现在很高兴并继续关注 Sammayd 关于实施 rand 的博客教程SammyD's Blog。
查看输出的屏幕截图。谢谢大家。
纵向图形看起来不太漂亮,欢迎任何建议。请注意,此处绘制的数据约为 4000+ data.I,我认为它可以更好地缩放,请分享我可以做些什么来使图表更像 iOS 股票应用程序。
根据您的 json 结构,我猜您的图表应该有 2 个系列。一个用于数据[0],一个用于数据[1]。如果我错了你可以编辑我的答案以满足你的需要。
首先,您可以创建 2 个有用的 类。第一个是 "ChartPoint":
@interface ChartPoint : NSObject
@property(strong,nonatomic) NSDate *date;
@property(strong,nonatomic) NSNumber *value;
@end
第二个是"ChartData":
@interface ChartData : NSObject
@property (strong,nonatomic) NSString *siteName;
@property (strong,nonatomic) NSMutableArray *chartPoints;
@end
其中将包含有关您的系列的信息。您系列的标题和一些 ChartPoints。
下一步是设置图表。您可以在 ShinobiChart 示例中看到这是如何完成的。这是一些代码:
-(void)setUpChart
{
schart = [[ShinobiChart alloc] initWithFrame:self.chartView.bounds];
schart.delegate=self;
schart.datasource = self;
schart.autoresizingMask = ~UIViewAutoresizingNone;
schart.licenseKey = @"your licence";
schart.legend.hidden=NO;
//X AXIS CONFIGURATION
SChartDateTimeAxis *xAxis = [[SChartDateTimeAxis alloc] init];
xAxis.style.interSeriesPadding = @0;
xAxis.style.majorTickStyle.showLabels = YES;
xAxis.style.majorTickStyle.showTicks = YES;
schart.xAxis = xAxis;
//Y AXIS CONFIGURATION
SChartAxis *yAxis = [[SChartNumberAxis alloc] init];
yAxis.style.majorGridLineStyle.showMajorGridLines=YES;
yAxis.style.majorTickStyle.showLabels = YES;
yAxis.style.majorTickStyle.showTicks = YES;
schart.yAxis = yAxis;
// add to the view
[self.chartView addSubview:schart];
}
之后您需要解析服务器的响应并创建上述有用的实例 类。如果您要绘制多个系列,您的视图控制器应该包含一个数组 "chartSeries" 和 "ChartData" objects。在反序列化对 NSDictionary 的响应后,您应该执行以下操作:
-(void)parseResponse:(NSDictionary*)response
{
chartSeries = [[NSMutableArray alloc] init];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm"];
NSArray *data = [response objectForKey:@"data"];
for (NSDictionary *d in data)
{
NSString *sitename = [d objectForKey:@"site_name"];
NSArray *records = [d objectForKey:@"records"];
ChartData *cd = [[ChartData alloc] init];
cd.siteName=sitename;
cd.chartPoints = [[NSMutableArray alloc] init];
for (NSArray *r in records)
{
NSString *dateString = [NSString stringWithFormat:@"%@",[r objectAtIndex:0]];
NSDate *date = [formatter dateFromString:dateString];
NSNumber *value = [r objectAtIndex:1];
ChartPoint *point =[[ChartPoint alloc] init];
point.date=date;
point.value = value;
[cd.chartPoints addObject:point];
}
[chartSeries addObject:cd];
}
[schart reloadData];
[schart redrawChart];
}
你看解析完成后,必须重新加载图表数据,重新绘制。这是因为 SChartDatasource 协议就像 UITableViews 一样。
- (NSInteger)numberOfSeriesInSChart:(ShinobiChart *)chart
{
return chartSeries.count;
}
- (NSInteger)sChart:(ShinobiChart *)chart numberOfDataPointsForSeriesAtIndex:(NSInteger)seriesIndex
{
ChartData * data = [chartSeries objectAtIndex:seriesIndex];
return data.chartPoints.count;
}
-(SChartSeries *)sChart:(ShinobiChart *)chart seriesAtIndex:(NSInteger)index
{
ChartData * data = [chartSeries objectAtIndex:index];
SChartColumnSeries *columnSeries = [[SChartColumnSeries alloc] init];
columnSeries.title=data.siteName;
return columnSeries;
}
- (id<SChartData>)sChart:(ShinobiChart *)chart dataPointAtIndex:(NSInteger)dataIndex forSeriesAtIndex:(NSInteger)seriesIndex
{
ChartData * data = [chartSeries objectAtIndex:seriesIndex];
ChartPoint *point = [data.chartPoints objectAtIndex:dataIndex];
SChartDataPoint *dp = [[SChartDataPoint alloc] init];
dp.yValue = point.value;
dp.xValue =point.date;
return dp;
}
希望对您有所帮助!
我在下面这个结构中绘制 json 数据时遇到问题。
{"response":{"hash":"0fea72f2bea9820c18227a655b42fe66","resp_code":"GRAPH_RETRIEVED","code":200},"resultstats":{"record_count":46},"ana_uoms":["°C"],"data":[{"asset_id":204,"company_id":30,"asset_name":"WIF","stats":{"min":1.4,"max":6.9,"min_tstamps_count":1,"min_tstamps":["2015-03-17 08:30:00"],"max_tstamps":["2015-03-17 11:00:00","2015-03-17 11:30:00","2015-03-17 13:40:00","2015-03-17 14:50:00"],"mkt":5.91,"max_tstamps_count":4,"avg":5.8},"component_type":"ana_in","component_description":"WFt","site_name":"Kll","alarms":[],"sampling_rate":10,"region_name":"ll","component_id":8340,"company_name":"lb","uom":"°C","uom_decimal_places":1,"unit_sn":"3310","resolves":[],"records":[["2015-03-17 08:00",2.6],["2015-03-17 08:10",3.9],["2015-03-17 08:20",2.4],["2015-03-17 08:30",1.4],["2015-03-17 08:40",3.1],["2015-03-17 08:50",4.4],["2015-03-17 09:00",5.1],["2015-03-17 09:10",5.5],["2015-03-17 09:20",6.1],["2015-03-17 09:30",6.2],["2015-03-17 09:40",5.3],["2015-03-17 09:50",6.4],["2015-03-17 10:00",6.6],["2015-03-17 10:10",6.7],["2015-03-17 10:20",6.8],["2015-03-17 10:30",5.2],["2015-03-17 10:40",6.3],["2015-03-17 10:50",6.7],["2015-03-17 11:00",6.9],["2015-03-17 11:10",6],["2015-03-17 11:20",6.6],["2015-03-17 11:30",6.9],["2015-03-17 11:40",5.9],["2015-03-17 11:50",6.6],["2015-03-17 12:00",6.8],["2015-03-17 12:10",6.1],["2015-03-17 12:20",6.6],["2015-03-17 12:30",5.6],["2015-03-17 12:40",6.2],["2015-03-17 12:50",6.8],["2015-03-17 13:00",5.7],["2015-03-17 13:10",6.6],["2015-03-17 13:20",5.8],["2015-03-17 13:30",6.4],["2015-03-17 13:40",6.9],["2015-03-17 13:50",6],["2015-03-17 14:00",6.7],["2015-03-17 14:10",5.2],["2015-03-17 14:20",6.5],["2015-03-17 14:30",5.8],["2015-03-17 14:40",6.3],["2015-03-17 14:50",6.9],["2015-03-17 15:00",6.6],["2015-03-17 15:10",5.9],["2015-03-17 15:20",6.3],["2015-03-17 15:30",6.5]]},{"asset_id":204,"company_id":30,"asset_name":"Wft","stats":{"min":2.9,"max":6.8,"min_tstamps_count":1,"min_tstamps":["2015-03-17 08:30:00"],"max_tstamps":["2015-03-17 11:00:00","2015-03-17 11:30:00","2015-03-17 12:00:00","2015-03-17 13:40:00"],"mkt":5.8,"max_tstamps_count":4,"avg":5.7},"component_type":"ana_in","component_description":"WIF Right Back","site_name":"Ktore","alarms":[],"sampling_rate":10,"region_name":"Kano","component_id":8341,"company_name":"lls","uom":"°C","uom_decimal_places":1,"unit_sn":"3310","resolves":[],"records":[["2015-03-17 08:00",3.2],["2015-03-17 08:10",4.2],["2015-03-17 08:20",3.1],["2015-03-17 08:30",2.9],["2015-03-17 08:40",3.7],["2015-03-17 08:50",4.5],["2015-03-17 09:00",5.2],["2015-03-17 09:10",5.6],["2015-03-17 09:20",6.1],["2015-03-17 09:30",6.3],["2015-03-17 09:40",4.8],["2015-03-17 09:50",6.3],["2015-03-17 10:00",6.5],["2015-03-17 10:10",6.6],["2015-03-17 10:20",6.7],["2015-03-17 10:30",4.5],["2015-03-17 10:40",6.3],["2015-03-17 10:50",6.6],["2015-03-17 11:00",6.8],["2015-03-17 11:10",5.9],["2015-03-17 11:20",6.5],["2015-03-17 11:30",6.8],["2015-03-17 11:40",5.7],["2015-03-17 11:50",6.5],["2015-03-17 12:00",6.8],["2015-03-17 12:10",5.9],["2015-03-17 12:20",6.6],["2015-03-17 12:30",5],["2015-03-17 12:40",6.2],["2015-03-17 12:50",6.7],["2015-03-17 13:00",5.5],["2015-03-17 13:10",6.5],["2015-03-17 13:20",5.2],["2015-03-17 13:30",6.2],["2015-03-17 13:40",6.8],["2015-03-17 13:50",5.8],["2015-03-17 14:00",6.6],["2015-03-17 14:10",4.5],["2015-03-17 14:20",6.4],["2015-03-17 14:30",5.2],["2015-03-17 14:40",6.2],["2015-03-17 14:50",6.7],["2015-03-17 15:00",6.4],["2015-03-17 15:10",5.2],["2015-03-17 15:20",6.2],["2015-03-17 15:30",6.1]]}],"ana_thresholds":[["<1.0"],[">8.0"]],"parameters":{"end_date":"2015-03-17 15:30","start_date":"2015-03-17 08:00","sampling_rate":10}}
我基本上是在尝试使用 Shinobi 图形库试用版来绘制此 json 数据,但我完全不知道如何解析上面的对象。在 json 中,我有日期时间和温度值。我设法在我的控制台中看到解析响应。但是该图没有要绘制的对象数据,因为我没有将任何 json 值传递给该系列,因为我不知道它是如何完成的。请提供帮助,因为我在 Whosebug 中没有看到类似的问题。
这是我的代码片段。
- (void) loadData{
// Parse units offline from the webservice.
@try{
NSString *delete = [[NSString alloc] initWithFormat:@""];
NSString *logOut = [NSString stringWithFormat:@"MY URL"];
NSURL *url=[NSURL URLWithString:logOut];
NSLog(@"Asset list: %@", url);
NSData *postData =[delete dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [ NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:@"GET"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setHTTPBody:postData];
//[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(@"Reponse code: %ld", (long)[response statusCode]);
if ([response statusCode] >= 200 && [response statusCode] < 300)
{
NSLog(@"Response ==> %@", responseData);
@try{
NSError *error = nil;
// NSMutableArray* jsonDetails = [[NSMutableArray alloc]init];
NSDictionary *jsonDetails = [NSJSONSerialization JSONObjectWithData:urlData options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error];
NSArray *graphData = [ jsonDetails objectForKey:@"records"];
NSLog(@"Retrieving graph: %@", jsonDetails);
for (NSDictionary* jsonPoint in graphData) {
SChartDataPoint* datapoint = [self dataPointForDate:jsonPoint[@"date"]
andValue:jsonPoint[@"temp"]];
NSLog(@"SChart point: %@", datapoint);
[_timeSeries addObject:datapoint];
}
}
@catch (NSException *e){
NSLog(@"Try catch block: %@", e);
}
@finally{
// [self.tblRegion reloadData];
NSLog(@"finally");
}
}
}
@catch (NSException * e) {
NSLog(@"Exception: %@", e);
}
}
A shinobichart 使用与 UITableView
相同的模型来提供数据 - 因为它使用数据源对象。您需要一个符合 SChartDatasource
协议的对象 - 它有 4 个必需的方法来向图表提供数据。其中包括提供数据点的数量和数据点本身(以及其他)。
如果您将正在创建的数据点保存到一个数组中,那么您就可以使用适当的 SChartDatasource
方法将它们传递给图表。
这里不再重复,我将向您介绍 shinobicharts 快速入门指南,其中贯穿了向图表提供数据的基础知识:
shinobicontrols.com/docs/ShinobiControls/ShinobiCharts/2.7.0/Premium/Normal/user_guide.html
您在此处的 JSON 结构有一个具有以下结构的记录字段:
"records":[["2015-03-17 08:00",2.6],["2015-03-17 08:10",3.9],...
这是一个数组数组 - 即每个数据点都由一个数组表示 - 第一个元素是日期,第二个元素是值。
您需要更新以下内容:
for (NSDictionary* jsonPoint in graphData) {
SChartDataPoint* datapoint = [self dataPointForDate:jsonPoint[@"date"]
andValue:jsonPoint[@"temp"]];
NSLog(@"SChart point: %@", datapoint);
[_timeSeries addObject:datapoint];
}
而不是 NSDictionary
个对象,你实际上有 NSArray
:
for (NSArray* jsonPoint in graphData) {
SChartDataPoint* datapoint = [self dataPointForDate:jsonPoint[0]
andValue:jsonPoint[1]];
NSLog(@"SChart point: %@", datapoint);
[_timeSeries addObject:datapoint];
}
请注意,您 可能 必须将日期值从 NSString
解析为 NSDate
- 取决于您的 dataPointForDate:andValue:
方法做。您可以使用 NSDateFormatter
.
感谢 sammyd 的帮助,相信这是对我问题的一个接近的答案。下面的片段几乎是完美的。唯一的问题是我仍然需要更改日期格式以获取系列中的数据点。
{
NSLog(@"Response ==> %@", responseData);
NSError *error = nil;
jsonDetails = [NSJSONSerialization JSONObjectWithData:urlData options:kNilOptions error:&error];
NSArray *keys = [jsonDetails allKeys];
// values in foreach loop
for (NSString *key in keys) {
// NSLog(@"%@ is %@",key, [jsonDetails objectForKey:key]);
data = [jsonDetails objectForKey:@"data"];
graphData = [data[0]objectForKey:@"records"];
datapoint = [[SChartDataPoint alloc] init];
// NSLog(@"Record for the graph: %@", graphData);
// results = [jsonDetails objectForKey:@"resultstats"];
// recordCount = [results objectForKey:@"record_count"];
for (int i=0; i< [graphData count]; i++){
NSArray *record = graphData[i];
// NSLog(@"Record value: %@", record);
datapoint.xValue = record[0]; // date
NSLog(@"Date/time: %@", datapoint.xValue);
datapoint.yValue = record[1]; // number
NSLog(@"Temp: %@", datapoint.yValue);
datapoint = [self dataPointForDate:datapoint.xValue
andValue:datapoint.yValue];
NSLog(@"Adding datapoint to series: %@", datapoint);
[_timeSeries addObject:datapoint];
}
}
}
这是控制台输出。我不会粘贴整个控制台输出,因为 json 响应和我用于调试 purpose.You 的 NSLog 在我将数据点对象添加到系列时出于某种原因可以看到。 datapoint.xValue 为空,因此我仍然没有在应用程序中看到图表。我已将日期格式更改为 yyyy-MM-dd HH:mm,这是我的控制台输出。仍然没有绘制图表。
TimeSeriesChart[952:468171] Adding datapoint to series: { index=0, x=2015-03-22 13:20:00 +0000, y=6.4, selected=N }
2015-03-23 07:49:01.682 TimeSeriesChart[952:468171] Date/time: 2015-03-22 15:30
2015-03-23 07:49:01.683 TimeSeriesChart[952:468171] Temp: 6.3
2015-03-23 07:49:01.685 TimeSeriesChart[952:468171] Time/Date format: 2015-03-22 13:30:00 +0000
2015-03-23 07:49:01.685 TimeSeriesChart[952:468171] Adding datapoint to series: { index=0, x=2015-03-22 13:30:00 +0000, y=6.3, selected=N }
2015-03-23 07:49:01.697 TimeSeriesChart[952:468171] ShinobiCharts: Attempting to update axis data range with nil series min or max. Axis range not updated.
From: SChartDateTimeAxis at 0x15d64d10, axisRange = { 0.000000, 1.000000 }, defaultRange = { 1970-01-01 00:00:00 +0000, 1970-01-01 00:00:01 +0000 }, maxRange = { 1970-01-01 00:00:00 +0000, 1970-01-01 00:00:01 +0000 }
2015-03-23 07:49:01.698 TimeSeriesChart[952:468171] ShinobiCharts: Attempting to update axis data range with nil series min or max. Axis range not updated.
From: SChartNumberAxis at 0x19c852e0, axisRange = { 0.000000, 1.000000 }, defaultRange = { 0.000000, 1.000000 }, maxRange = { 0.000000, 1.000000 }
我按照 sammyd 的建议回答修复了上述错误;
for (NSArray *record in graphData) {
// NSArray *record = graphData[i];
// NSLog(@"Record value: %@", record);
NSString *dateString = [NSString stringWithFormat:@"%@",[record objectAtIndex:0]];
NSDate *date = [self dateFromString:dateString];
datapoint.xValue = date; // date
NSLog(@"Date/time: %@", datapoint.xValue);
// NSString *date = datapoint.xValue;
datapoint.yValue = record[1]; // number
NSLog(@"Temp: %@", datapoint.yValue);
datapoint = [self dataPointForDate:record[0]
andValue:record[1]];
NSLog(@"Adding datapoint to series: %@", datapoint);
[_timeSeries addObject:datapoint];
}
我现在很高兴并继续关注 Sammayd 关于实施 rand 的博客教程SammyD's Blog。
查看输出的屏幕截图。谢谢大家。
纵向图形看起来不太漂亮,欢迎任何建议。请注意,此处绘制的数据约为 4000+ data.I,我认为它可以更好地缩放,请分享我可以做些什么来使图表更像 iOS 股票应用程序。
根据您的 json 结构,我猜您的图表应该有 2 个系列。一个用于数据[0],一个用于数据[1]。如果我错了你可以编辑我的答案以满足你的需要。
首先,您可以创建 2 个有用的 类。第一个是 "ChartPoint":
@interface ChartPoint : NSObject
@property(strong,nonatomic) NSDate *date;
@property(strong,nonatomic) NSNumber *value;
@end
第二个是"ChartData":
@interface ChartData : NSObject
@property (strong,nonatomic) NSString *siteName;
@property (strong,nonatomic) NSMutableArray *chartPoints;
@end
其中将包含有关您的系列的信息。您系列的标题和一些 ChartPoints。
下一步是设置图表。您可以在 ShinobiChart 示例中看到这是如何完成的。这是一些代码:
-(void)setUpChart
{
schart = [[ShinobiChart alloc] initWithFrame:self.chartView.bounds];
schart.delegate=self;
schart.datasource = self;
schart.autoresizingMask = ~UIViewAutoresizingNone;
schart.licenseKey = @"your licence";
schart.legend.hidden=NO;
//X AXIS CONFIGURATION
SChartDateTimeAxis *xAxis = [[SChartDateTimeAxis alloc] init];
xAxis.style.interSeriesPadding = @0;
xAxis.style.majorTickStyle.showLabels = YES;
xAxis.style.majorTickStyle.showTicks = YES;
schart.xAxis = xAxis;
//Y AXIS CONFIGURATION
SChartAxis *yAxis = [[SChartNumberAxis alloc] init];
yAxis.style.majorGridLineStyle.showMajorGridLines=YES;
yAxis.style.majorTickStyle.showLabels = YES;
yAxis.style.majorTickStyle.showTicks = YES;
schart.yAxis = yAxis;
// add to the view
[self.chartView addSubview:schart];
}
之后您需要解析服务器的响应并创建上述有用的实例 类。如果您要绘制多个系列,您的视图控制器应该包含一个数组 "chartSeries" 和 "ChartData" objects。在反序列化对 NSDictionary 的响应后,您应该执行以下操作:
-(void)parseResponse:(NSDictionary*)response
{
chartSeries = [[NSMutableArray alloc] init];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm"];
NSArray *data = [response objectForKey:@"data"];
for (NSDictionary *d in data)
{
NSString *sitename = [d objectForKey:@"site_name"];
NSArray *records = [d objectForKey:@"records"];
ChartData *cd = [[ChartData alloc] init];
cd.siteName=sitename;
cd.chartPoints = [[NSMutableArray alloc] init];
for (NSArray *r in records)
{
NSString *dateString = [NSString stringWithFormat:@"%@",[r objectAtIndex:0]];
NSDate *date = [formatter dateFromString:dateString];
NSNumber *value = [r objectAtIndex:1];
ChartPoint *point =[[ChartPoint alloc] init];
point.date=date;
point.value = value;
[cd.chartPoints addObject:point];
}
[chartSeries addObject:cd];
}
[schart reloadData];
[schart redrawChart];
}
你看解析完成后,必须重新加载图表数据,重新绘制。这是因为 SChartDatasource 协议就像 UITableViews 一样。
- (NSInteger)numberOfSeriesInSChart:(ShinobiChart *)chart
{
return chartSeries.count;
}
- (NSInteger)sChart:(ShinobiChart *)chart numberOfDataPointsForSeriesAtIndex:(NSInteger)seriesIndex
{
ChartData * data = [chartSeries objectAtIndex:seriesIndex];
return data.chartPoints.count;
}
-(SChartSeries *)sChart:(ShinobiChart *)chart seriesAtIndex:(NSInteger)index
{
ChartData * data = [chartSeries objectAtIndex:index];
SChartColumnSeries *columnSeries = [[SChartColumnSeries alloc] init];
columnSeries.title=data.siteName;
return columnSeries;
}
- (id<SChartData>)sChart:(ShinobiChart *)chart dataPointAtIndex:(NSInteger)dataIndex forSeriesAtIndex:(NSInteger)seriesIndex
{
ChartData * data = [chartSeries objectAtIndex:seriesIndex];
ChartPoint *point = [data.chartPoints objectAtIndex:dataIndex];
SChartDataPoint *dp = [[SChartDataPoint alloc] init];
dp.yValue = point.value;
dp.xValue =point.date;
return dp;
}
希望对您有所帮助!