Core Plot チャートのプロット値については、軸NSDate
に基づいた値を表示しています。x
値は何年にもわたり、毎日プロットされます。
x
年または月ごとに - 軸にラベルを表示したいのですが、日ごとではありません。これが、Core Plot サンプル アプリに示されているラベル付け方法を使用できない理由ですDatePlot
。
現在、ラベルを手動で作成しています (次のコード スニペットに示すように)。残念ながら、このソリューションは、以下のスクリーン ショットに示す問題につながります (2001 年のラベルが 2002 に近すぎます)。
[sortedArray enumerateObjectsUsingBlock:
^(Price *priceItem, NSUInteger idx, BOOL *stop) {
NSDateComponents *yearComponents =
[gregorian components:NSYearCalendarUnit
fromDate:price.dateTime];
NSDateComponents *monthComponents =
[gregorian components:NSMonthCalendarUnit
fromDate:price.dateTime];
NSInteger year = [yearComponents year];
NSInteger month = [monthComponents month];
if (month != previousMonth) {
[minorTickLocations addObject:
[NSDecimalNumber numberWithUnsignedInteger:idx]];
previousMonth = month;
}
if (year != previousYear) {
CPTAxisLabel *newLabel = [[CPTAxisLabel alloc]
initWithText: [NSString stringWithFormat:@"%u", year]
textStyle: axisTitleTextStyle];
newLabel.tickLocation = CPTDecimalFromUnsignedInteger(idx);
newLabel.offset = x.labelOffset + x.majorTickLength / 2.0;
[xAxisLabels addObject:newLabel];
[majorTickLocations addObject:
[NSDecimalNumber numberWithUnsignedInteger:idx]];
previousYear = year;
}
}];
標準の Core Plot メソッドを使用してこれをコーディングするより良い方法があるかどうか疑問に思っています。
日付フォーマッタの動作を使用して、年のみ ( YYYY
)、月と年 ( MMM-YYYY
)、または月のみ( ) を表示できると便利MMM
です。
編集
エリックが彼の投稿で推奨したように、使用できるようにするために、日付を年の分数に変換していますCPTDateFormatter
。これは私がチャートを設定する方法です(最初は、暦年ごとにティックをプロットしたいだけです):
x.labelingPolicy = CPTAxisLabelingPolicyFixedInterval;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy"];
CPTCalendarFormatter *calendarFormatter = [[CPTCalendarFormatter alloc]
initWithDateFormatter:dateFormatter];
calendarFormatter.referenceDate = [sortedPrices[0]
valueForKey:@"dateTime"];
calendarFormatter.referenceCalendarUnit = NSYearCalendarUnit;
x.labelFormatter = calendarFormatter;
これは、最初の整数ベースのインデックスを「年の端数」ベースのインデックスに変換する方法です。
- (NSArray*)indexArrayOfDatesArray:(NSArray*)dates
{
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *startDate = [sortedCommonSharePrices[0] valueForKey:@"dateTime"];
NSDateComponents *yearComponents = [gregorian components: NSYearCalendarUnit
fromDate:startDate];
NSUInteger startYear = yearComponents.year;
NSMutableArray *array = [NSMutableArray arrayWithCapacity:dates.count];
[dates enumerateObjectsUsingBlock:^(NSDate *date, NSUInteger idx, BOOL *stop) {
NSDateComponents *yearComponents = [gregorian
components:NSYearCalendarUnit fromDate:date];
NSInteger years = [yearComponents year];
NSUInteger numberOfDaysSinceStartOfYear =
[gregorian ordinalityOfUnit:NSDayCalendarUnit
inUnit:NSYearCalendarUnit forDate:date];
NSUInteger totalNumberOfDaysInYear = 365;
double fractionOfYear = (double)numberOfDaysSinceStartOfYear /
(double)totalNumberOfDaysInYear + (double)years - (double)startYear;
[array addObject:[NSNumber numberWithDouble:fractionOfYear]];
}];
return array;
}
これは問題なく動作するように見えますが、多くのコードのようです (コードを改善するための考えはありますか?)。
質問
( を使用して) ズームとパンを行うときplotSpace:willChangePlotRangeTo
、x 軸のラベルを新しい日付範囲に設定したい (新しいプロット範囲の日数に基づく)。ただし、目盛りの数とラベルが正しくない (を参照してください)下のスクリーンショット)。
ラベル付けを正しく行うには、ラベル付けパラメーターをどのように設定する必要がありますか?
ご協力ありがとう御座います!
からのコード スニペットplotSpace:willChangePlotRangeTo
:
NSDateComponents *components = [gregorian components:NSDayCalendarUnit
fromDate:newStartDate toDate:newEndDate options:0];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
CPTCalendarFormatter *calendarFormatter =
[[CPTCalendarFormatter alloc] initWithDateFormatter:dateFormatter];
calendarFormatter.referenceDate = [sortedPrices[0] valueForKey:@"dateTime"];
if (components.day < 365) {
dateFormatter.dateFormat = @"ddd-MMM-yyyy";
calendarFormatter.referenceCalendarUnit = NSDayCalendarUnit;
} else if (components.day < 365 * 2) {
dateFormatter.dateFormat = @"MMM yyyy";
calendarFormatter.referenceCalendarUnit = NSYearCalendarUnit;
} else if (components.day < 365 * 4) {
dateFormatter.dateFormat = @"qqq yyyy";
calendarFormatter.referenceCalendarUnit = NSYearCalendarUnit;
} else {
dateFormatter.dateFormat = @"yyyy";
calendarFormatter.referenceCalendarUnit = NSYearCalendarUnit;
}
CPTXYAxis *x = axisSet.xAxis;
x.preferredNumberOfMajorTicks = 10;
x.majorIntervalLength = CPTDecimalFromDouble(0.1);
x.minorTicksPerInterval = 1;
x.labelFormatter = calendarFormatter;