0

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;

間違った目盛りとラベル

4

2 に答える 2

4

次のように、独自のラベル付けポリシーを提供します。

...
CPTXYAxis *x = axisSet.xAxis;
int totalNumberOfYearsToShow = 3;
int startYear = 2010;
int i = 0;
NSMutableSet *xLabels = [NSMutableSet setWithCapacity:totalRecords];
NSMutableSet *xLocations = [NSMutableSet setWithCapacity:totalRecords];

while (i < totalNumberOfYearsToShow)
{
    NSNumber *xData = [NSNumber numberWithInt:(i + startYear)];
    CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[xData stringValue] textStyle:x.labelTextStyle];
    label.tickLocation = CPTDecimalFromInt([xData intValue]);
    label.offset = x.majorTickLength;

    if (label)
    {
        [xLabels addObject:label];
        [xLocations addObject:xData];
    }

    i ++;
}


x.labelingPolicy = CPTAxisLabelingPolicyNone;
x.axisLabels = xLabels;
x.majorTickLocations = xLocations;
...

それが役立つことを願っています。

于 2013-02-15T22:30:27.820 に答える
1

Core Plot サンプル アプリ DatePlot に示されているラベル付け方法を使用できません。

なぜだめですか?固定間隔のラベル付けポリシーでは、majorIntervalLengthを 1 年に相当する値に設定し、CPTCalendarFormatterまたはを使用しCPTTimeFormatterてラベルをフォーマットします。

于 2013-02-10T14:06:29.743 に答える