2013-12-03 3 views
2

Я пытаюсь отформатировать длинные числа в форме «k» для меток оси. Например; если у меня есть , я бы хотел, чтобы он отображался как 10k.Форматировать длинные номера для осевых меток основной сюжет

Я уже пытался ответить this ответ. Но мне не удалось получить форматированные числа. Что мне нужно сделать дополнительно? Пожалуйста, направляйте меня. Благодарю.

EDIT:

HumanReadableFormatter.h

@interface HumanReadableFormatter : NSNumberFormatter 

@end 

HumanReadableFormatter.m

Я изменил код из ссылки выше, чтобы соответствовать моим требованиям.

#import "HumanReadableFormatter.h" 

@implementation HumanReadableFormatter 

static const char sUnits[] = { '\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' }; 
static int sMaxUnits = sizeof sUnits - 1; 

    -(NSString *) stringForObjectValue:(id)obj 
{ 
    int multiplier = 1000; 
    int exponent = 0; 

    double bytes = [(NSNumber *)obj doubleValue]; 

    while ((bytes >= multiplier) && (exponent < sMaxUnits)) { 
     bytes /= multiplier; 
     exponent++; 
    } 
    return [NSString stringWithFormat:@"%@ %c", [super stringFromNumber: [NSNumber numberWithDouble: bytes]], sUnits[exponent]]; 

} 

@end 

График Код:

if(!rightY) 
    rightY = [[CPTXYAxis alloc]init]; 
rightY.labelingPolicy = CPTAxisLabelingPolicyAutomatic; 
rightY.orthogonalCoordinateDecimal = CPTDecimalFromFloat(totIntervalShown); 
rightY.axisConstraints = [CPTConstraints constraintWithUpperOffset:-40]; 
rightY.coordinate = CPTCoordinateY; 
rightY.majorTickLength = 0; 
rightY.minorTickLength = 0; 
rightY.tickDirection = CPTSignNone; 
rightY.plotSpace = barPlotSpace; 

NSNumberFormatter *numFormatter; 
if(lowerLock < 1000) //if value is < 1000, normally format it 
{ 
numFormatter = [[NSNumberFormatter alloc] init]; 
[numFormatter setNumberStyle: NSNumberFormatterDecimalStyle]; 
numFormatter.maximumFractionDigits = 2; 
numFormatter.minimumFractionDigits = 2; 
} 
else //for > 1000, format in human readable form 
{ 
    numFormatter = [[HumanReadableFormatter alloc] init]; 
//what i need to do here more? 
} 
rightY.labelFormatter = numFormatter; 

//formatted as shown on right side on graph 

enter image description here

вложенного цикла:

enter image description here

+0

Привет @NightFury, Как u построить правую сторону оси Y с inte rval и plot. пожалуйста, помогите мне в этом – Marios

ответ

5

Я отправляю решение, если кому-то это понадобится в будущем. Спасибо @ Eric за то, что помогли мне.

HumanReadableFormatter.h

@interface HumanReadableFormatter : NSNumberFormatter 
{ 
    NSNumberFormatter *numberFormatter; 
} 

@end 

HumanReadableFormatter.m

@implementation HumanReadableFormatter 

static const char sUnits[] = { '\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' }; 
static int sMaxUnits = sizeof sUnits - 1; 

-(id)init 
{ 
    if(self = [super init]) 
    { 
     numberFormatter = [[NSNumberFormatter alloc] init]; 
     [numberFormatter setNumberStyle: NSNumberFormatterDecimalStyle]; 
     numberFormatter.maximumFractionDigits = 1; 
     numberFormatter.minimumFractionDigits = 1; 

    } 
    return self; 
} 

-(NSString *) stringForObjectValue:(id)obj 
{ 
    int multiplier = 1000; 
    int exponent = 0; 

    double bytes = [(NSNumber *)obj doubleValue]; 

    while ((bytes >= multiplier) && (exponent < sMaxUnits)) { 
     bytes /= multiplier; 
     exponent++; 
    } 
    NSString *convertedStr = [NSString stringWithFormat:@"%@ %c", [numberFormatter stringFromNumber: [NSNumber numberWithDouble: bytes]], sUnits[exponent]]; 

    return convertedStr; 

} 

@end 

Для использования в графике, необходимо 2 строки кода:

HumanReadableFormatter *formatter = [[HumanReadableFormatter alloc] init]; 
YAxis.labelFormatter = formatter; 
+0

Сэр, ты сделал свой день. – PhilippeAuriach

+0

Спасибо @iAnum за код – yogs

2

Si, nce labelFormatter использует NSFormatter, ваш пользовательский форматтер должен переопределять -stringForObjectValue:, а не -stringFromNumber:, который относится к NSNumberFormatter. Передайте аргумент NSNumber, и вы можете использовать тот же код для тела метода.

+0

Спасибо Эрик за ваш ответ. Я попытался реализовать то, что вы сказали, но мой код застрял в некотором вложенном вызове функции, как я показал на рис. Я заметил, что он застревает в return statement в методе форматирования 'stringForObjectValue'. – NightFury

+0

Вы рекурсивно вызываете форматтер для форматирования. Используйте другой форматтер, чтобы отформатировать номер после определения экспоненты. Храните его в переменной экземпляра в вашем классе форматирования, поэтому вам не нужно создавать новый каждый раз, когда вам нужно отформатировать номер. Посмотрите на «CPTCalendarFormatter» или «CPTTimeFormatter», например, на код. –

+0

Спасибо Эрик. Ты сделал мой день :) – NightFury